]> git.xolatile.top Git - emil-xolatilization.git/commitdiff
Just dumped everything because...
authorxolatile <xolatile@proton.me>
Sun, 6 Apr 2025 14:01:15 +0000 (16:01 +0200)
committerxolatile <xolatile@proton.me>
Sun, 6 Apr 2025 14:01:15 +0000 (16:01 +0200)
596 files changed:
.gitignore [new file with mode: 0755]
LICENSE [new file with mode: 0755]
README.md [new file with mode: 0755]
compile.sh [new file with mode: 0755]
install.sh [new file with mode: 0755]
test [new file with mode: 0755]
test.c [new file with mode: 0644]
xachine.h [new file with mode: 0755]
xanguage.h [new file with mode: 0755]
xanguage/ada.h [new file with mode: 0755]
xanguage/bash.h [new file with mode: 0755]
xanguage/c++.h [new file with mode: 0755]
xanguage/c.h [new file with mode: 0755]
xanguage/common.h [new file with mode: 0755]
xanguage/d.h [new file with mode: 0755]
xanguage/eaxhla.h [new file with mode: 0755]
xanguage/flat.h [new file with mode: 0755]
xanguage/fortran.h [new file with mode: 0755]
xanguage/go.h [new file with mode: 0755]
xanguage/haskell.h [new file with mode: 0755]
xanguage/lua.h [new file with mode: 0755]
xanguage/pascal.h [new file with mode: 0755]
xanguage/python.h [new file with mode: 0755]
xanguage/valgrind.h [new file with mode: 0755]
xanual/adc.md [new file with mode: 0755]
xanual/add.md [new file with mode: 0755]
xanual/and.md [new file with mode: 0755]
xanual/call.md [new file with mode: 0755]
xanual/cmovcc.md [new file with mode: 0755]
xanual/cmp.md [new file with mode: 0755]
xanual/dec.md [new file with mode: 0755]
xanual/div.md [new file with mode: 0755]
xanual/enter.md [new file with mode: 0755]
xanual/idiv.md [new file with mode: 0755]
xanual/imul.md [new file with mode: 0755]
xanual/inc.md [new file with mode: 0755]
xanual/jcc.md [new file with mode: 0755]
xanual/jmp.md [new file with mode: 0755]
xanual/leave.md [new file with mode: 0755]
xanual/mov.md [new file with mode: 0755]
xanual/mul.md [new file with mode: 0755]
xanual/neg.md [new file with mode: 0755]
xanual/nop.md [new file with mode: 0755]
xanual/not.md [new file with mode: 0755]
xanual/or.md [new file with mode: 0755]
xanual/pop.md [new file with mode: 0755]
xanual/push.md [new file with mode: 0755]
xanual/ret.md [new file with mode: 0755]
xanual/rot.md [new file with mode: 0755]
xanual/sbb.md [new file with mode: 0755]
xanual/setcc.md [new file with mode: 0755]
xanual/sft.md [new file with mode: 0755]
xanual/sub.md [new file with mode: 0755]
xanual/syscall.md [new file with mode: 0755]
xanual/sysenter.md [new file with mode: 0755]
xanual/sysexit.md [new file with mode: 0755]
xanual/sysret.md [new file with mode: 0755]
xanual/template.md [new file with mode: 0755]
xanual/xor.md [new file with mode: 0755]
xaptor [new file with mode: 0755]
xaptor.c [new file with mode: 0644]
xaptor.h [new file with mode: 0644]
xarbon.c [new file with mode: 0755]
xarticle.h [new file with mode: 0644]
xatrix.h [new file with mode: 0644]
xcript.h [new file with mode: 0755]
xector.h [new file with mode: 0755]
xhallenge.c [new file with mode: 0755]
xhallenge_list.cfg [new file with mode: 0755]
xiasma.h [new file with mode: 0755]
xighlight.c [new file with mode: 0755]
xogueout [new file with mode: 0755]
xogueout.c [new file with mode: 0644]
xommon.h [new file with mode: 0755]
xop.c [new file with mode: 0755]
xormat.h [new file with mode: 0644]
xormat/jxl.h [new file with mode: 0644]
xormat/png.h [new file with mode: 0644]
xpenal.h [new file with mode: 0755]
xpengl.h [new file with mode: 0755]
xphere.h [new file with mode: 0755]
xprite.h [new file with mode: 0755]
xrocessor.h [new file with mode: 0755]
xross.h [new file with mode: 0755]
xscii.c [new file with mode: 0755]
xtandard.h [new file with mode: 0755]
xui.h [new file with mode: 0755]
xui/common/fullscreen_off.png [new file with mode: 0755]
xui/common/fullscreen_on.png [new file with mode: 0755]
xui/common/map_preview_panel_off.png [new file with mode: 0755]
xui/common/map_preview_panel_on.png [new file with mode: 0755]
xui/common/monospace.png [new file with mode: 0755]
xui/common/palette.png [new file with mode: 0755]
xui/common/regular.png [new file with mode: 0755]
xui/common/status_preview_panel_off.png [new file with mode: 0755]
xui/common/status_preview_panel_on.png [new file with mode: 0755]
xui/common/text_box_panel_off.png [new file with mode: 0755]
xui/common/text_box_panel_on.png [new file with mode: 0755]
xui/dwarf/button_left.png [new file with mode: 0755]
xui/dwarf/button_lower.png [new file with mode: 0755]
xui/dwarf/button_lower_left.png [new file with mode: 0755]
xui/dwarf/button_lower_right.png [new file with mode: 0755]
xui/dwarf/button_middle.png [new file with mode: 0755]
xui/dwarf/button_right.png [new file with mode: 0755]
xui/dwarf/button_upper.png [new file with mode: 0755]
xui/dwarf/button_upper_left.png [new file with mode: 0755]
xui/dwarf/button_upper_right.png [new file with mode: 0755]
xui/dwarf/check_box_off.png [new file with mode: 0755]
xui/dwarf/check_box_on.png [new file with mode: 0755]
xui/dwarf/cursor.png [new file with mode: 0755]
xui/dwarf/end_turn_button.png [new file with mode: 0755]
xui/dwarf/fill_bar_base.png [new file with mode: 0755]
xui/dwarf/fill_bar_left.png [new file with mode: 0755]
xui/dwarf/fill_bar_middle.png [new file with mode: 0755]
xui/dwarf/fill_bar_right.png [new file with mode: 0755]
xui/dwarf/frame_left.png [new file with mode: 0755]
xui/dwarf/frame_lower.png [new file with mode: 0755]
xui/dwarf/frame_lower_left.png [new file with mode: 0755]
xui/dwarf/frame_lower_right.png [new file with mode: 0755]
xui/dwarf/frame_right.png [new file with mode: 0755]
xui/dwarf/frame_upper.png [new file with mode: 0755]
xui/dwarf/frame_upper_left.png [new file with mode: 0755]
xui/dwarf/frame_upper_right.png [new file with mode: 0755]
xui/dwarf/icon_frame.png [new file with mode: 0755]
xui/dwarf/menu_left.png [new file with mode: 0755]
xui/dwarf/menu_lower.png [new file with mode: 0755]
xui/dwarf/menu_lower_left.png [new file with mode: 0755]
xui/dwarf/menu_lower_right.png [new file with mode: 0755]
xui/dwarf/menu_middle.png [new file with mode: 0755]
xui/dwarf/menu_right.png [new file with mode: 0755]
xui/dwarf/menu_upper.png [new file with mode: 0755]
xui/dwarf/menu_upper_left.png [new file with mode: 0755]
xui/dwarf/menu_upper_right.png [new file with mode: 0755]
xui/dwarf/overicon_frame.png [new file with mode: 0755]
xui/dwarf/scroll_bar_lower.png [new file with mode: 0755]
xui/dwarf/scroll_bar_middle.png [new file with mode: 0755]
xui/dwarf/scroll_bar_slider.png [new file with mode: 0755]
xui/dwarf/scroll_bar_upper.png [new file with mode: 0755]
xui/dwarf/separator_center.png [new file with mode: 0755]
xui/dwarf/separator_left.png [new file with mode: 0755]
xui/dwarf/separator_middle.png [new file with mode: 0755]
xui/dwarf/separator_right.png [new file with mode: 0755]
xui/dwarf/status_left.png [new file with mode: 0755]
xui/dwarf/status_lower.png [new file with mode: 0755]
xui/dwarf/status_lower_left.png [new file with mode: 0755]
xui/dwarf/status_lower_right.png [new file with mode: 0755]
xui/dwarf/status_middle.png [new file with mode: 0755]
xui/dwarf/status_right.png [new file with mode: 0755]
xui/dwarf/status_upper.png [new file with mode: 0755]
xui/dwarf/status_upper_left.png [new file with mode: 0755]
xui/dwarf/status_upper_right.png [new file with mode: 0755]
xui/dwarf/tiny_fill_bar_base.png [new file with mode: 0755]
xui/dwarf/tiny_fill_bar_left.png [new file with mode: 0755]
xui/dwarf/tiny_fill_bar_middle.png [new file with mode: 0755]
xui/dwarf/tiny_fill_bar_right.png [new file with mode: 0755]
xui/dwarf/title_bar_left.png [new file with mode: 0755]
xui/dwarf/title_bar_middle.png [new file with mode: 0755]
xui/dwarf/title_bar_right.png [new file with mode: 0755]
xui/dwarf/ubericon_frame.png [new file with mode: 0755]
xui/dwarf/window_left.png [new file with mode: 0755]
xui/dwarf/window_lower.png [new file with mode: 0755]
xui/dwarf/window_lower_left.png [new file with mode: 0755]
xui/dwarf/window_lower_right.png [new file with mode: 0755]
xui/dwarf/window_right.png [new file with mode: 0755]
xui/dwarf/window_upper.png [new file with mode: 0755]
xui/dwarf/window_upper_left.png [new file with mode: 0755]
xui/dwarf/window_upper_right.png [new file with mode: 0755]
xui/fairy/button_left.png [new file with mode: 0755]
xui/fairy/button_lower.png [new file with mode: 0755]
xui/fairy/button_lower_left.png [new file with mode: 0755]
xui/fairy/button_lower_right.png [new file with mode: 0755]
xui/fairy/button_middle.png [new file with mode: 0755]
xui/fairy/button_right.png [new file with mode: 0755]
xui/fairy/button_upper.png [new file with mode: 0755]
xui/fairy/button_upper_left.png [new file with mode: 0755]
xui/fairy/button_upper_right.png [new file with mode: 0755]
xui/fairy/check_box_off.png [new file with mode: 0755]
xui/fairy/check_box_on.png [new file with mode: 0755]
xui/fairy/cursor.png [new file with mode: 0755]
xui/fairy/end_turn_button.png [new file with mode: 0755]
xui/fairy/fill_bar_base.png [new file with mode: 0755]
xui/fairy/fill_bar_left.png [new file with mode: 0755]
xui/fairy/fill_bar_middle.png [new file with mode: 0755]
xui/fairy/fill_bar_right.png [new file with mode: 0755]
xui/fairy/frame_left.png [new file with mode: 0755]
xui/fairy/frame_lower.png [new file with mode: 0755]
xui/fairy/frame_lower_left.png [new file with mode: 0755]
xui/fairy/frame_lower_right.png [new file with mode: 0755]
xui/fairy/frame_right.png [new file with mode: 0755]
xui/fairy/frame_upper.png [new file with mode: 0755]
xui/fairy/frame_upper_left.png [new file with mode: 0755]
xui/fairy/frame_upper_right.png [new file with mode: 0755]
xui/fairy/icon_frame.png [new file with mode: 0755]
xui/fairy/menu_left.png [new file with mode: 0755]
xui/fairy/menu_lower.png [new file with mode: 0755]
xui/fairy/menu_lower_left.png [new file with mode: 0755]
xui/fairy/menu_lower_right.png [new file with mode: 0755]
xui/fairy/menu_middle.png [new file with mode: 0755]
xui/fairy/menu_right.png [new file with mode: 0755]
xui/fairy/menu_upper.png [new file with mode: 0755]
xui/fairy/menu_upper_left.png [new file with mode: 0755]
xui/fairy/menu_upper_right.png [new file with mode: 0755]
xui/fairy/overicon_frame.png [new file with mode: 0755]
xui/fairy/scroll_bar_lower.png [new file with mode: 0755]
xui/fairy/scroll_bar_middle.png [new file with mode: 0755]
xui/fairy/scroll_bar_slider.png [new file with mode: 0644]
xui/fairy/scroll_bar_upper.png [new file with mode: 0755]
xui/fairy/separator_center.png [new file with mode: 0644]
xui/fairy/separator_left.png [new file with mode: 0755]
xui/fairy/separator_middle.png [new file with mode: 0755]
xui/fairy/separator_right.png [new file with mode: 0755]
xui/fairy/status_left.png [new file with mode: 0755]
xui/fairy/status_lower.png [new file with mode: 0755]
xui/fairy/status_lower_left.png [new file with mode: 0755]
xui/fairy/status_lower_right.png [new file with mode: 0755]
xui/fairy/status_middle.png [new file with mode: 0755]
xui/fairy/status_right.png [new file with mode: 0755]
xui/fairy/status_upper.png [new file with mode: 0755]
xui/fairy/status_upper_left.png [new file with mode: 0755]
xui/fairy/status_upper_right.png [new file with mode: 0755]
xui/fairy/tiny_fill_bar_base.png [new file with mode: 0755]
xui/fairy/tiny_fill_bar_left.png [new file with mode: 0755]
xui/fairy/tiny_fill_bar_middle.png [new file with mode: 0755]
xui/fairy/tiny_fill_bar_right.png [new file with mode: 0755]
xui/fairy/title_bar_left.png [new file with mode: 0755]
xui/fairy/title_bar_middle.png [new file with mode: 0755]
xui/fairy/title_bar_right.png [new file with mode: 0755]
xui/fairy/ubericon_frame.png [new file with mode: 0755]
xui/fairy/window_left.png [new file with mode: 0755]
xui/fairy/window_lower.png [new file with mode: 0755]
xui/fairy/window_lower_left.png [new file with mode: 0755]
xui/fairy/window_lower_right.png [new file with mode: 0755]
xui/fairy/window_right.png [new file with mode: 0755]
xui/fairy/window_upper.png [new file with mode: 0755]
xui/fairy/window_upper_left.png [new file with mode: 0755]
xui/fairy/window_upper_right.png [new file with mode: 0755]
xui/fullscreen_off.png [new file with mode: 0755]
xui/fullscreen_on.png [new file with mode: 0755]
xui/gnoll/button_left.png [new file with mode: 0755]
xui/gnoll/button_lower.png [new file with mode: 0755]
xui/gnoll/button_lower_left.png [new file with mode: 0755]
xui/gnoll/button_lower_right.png [new file with mode: 0755]
xui/gnoll/button_middle.png [new file with mode: 0755]
xui/gnoll/button_right.png [new file with mode: 0755]
xui/gnoll/button_upper.png [new file with mode: 0755]
xui/gnoll/button_upper_left.png [new file with mode: 0755]
xui/gnoll/button_upper_right.png [new file with mode: 0755]
xui/gnoll/check_box_off.png [new file with mode: 0755]
xui/gnoll/check_box_on.png [new file with mode: 0755]
xui/gnoll/cursor.png [new file with mode: 0755]
xui/gnoll/end_turn_button.png [new file with mode: 0755]
xui/gnoll/fill_bar_base.png [new file with mode: 0755]
xui/gnoll/fill_bar_left.png [new file with mode: 0755]
xui/gnoll/fill_bar_middle.png [new file with mode: 0755]
xui/gnoll/fill_bar_right.png [new file with mode: 0755]
xui/gnoll/frame_left.png [new file with mode: 0755]
xui/gnoll/frame_lower.png [new file with mode: 0755]
xui/gnoll/frame_lower_left.png [new file with mode: 0755]
xui/gnoll/frame_lower_right.png [new file with mode: 0755]
xui/gnoll/frame_right.png [new file with mode: 0755]
xui/gnoll/frame_upper.png [new file with mode: 0755]
xui/gnoll/frame_upper_left.png [new file with mode: 0755]
xui/gnoll/frame_upper_right.png [new file with mode: 0755]
xui/gnoll/icon_frame.png [new file with mode: 0755]
xui/gnoll/menu_left.png [new file with mode: 0755]
xui/gnoll/menu_lower.png [new file with mode: 0755]
xui/gnoll/menu_lower_left.png [new file with mode: 0755]
xui/gnoll/menu_lower_right.png [new file with mode: 0755]
xui/gnoll/menu_middle.png [new file with mode: 0755]
xui/gnoll/menu_right.png [new file with mode: 0755]
xui/gnoll/menu_upper.png [new file with mode: 0755]
xui/gnoll/menu_upper_left.png [new file with mode: 0755]
xui/gnoll/menu_upper_right.png [new file with mode: 0755]
xui/gnoll/overicon_frame.png [new file with mode: 0755]
xui/gnoll/scroll_bar_lower.png [new file with mode: 0755]
xui/gnoll/scroll_bar_middle.png [new file with mode: 0755]
xui/gnoll/scroll_bar_slider.png [new file with mode: 0755]
xui/gnoll/scroll_bar_upper.png [new file with mode: 0755]
xui/gnoll/separator_center.png [new file with mode: 0755]
xui/gnoll/separator_left.png [new file with mode: 0755]
xui/gnoll/separator_middle.png [new file with mode: 0755]
xui/gnoll/separator_right.png [new file with mode: 0755]
xui/gnoll/status_left.png [new file with mode: 0755]
xui/gnoll/status_lower.png [new file with mode: 0755]
xui/gnoll/status_lower_left.png [new file with mode: 0755]
xui/gnoll/status_lower_right.png [new file with mode: 0755]
xui/gnoll/status_middle.png [new file with mode: 0755]
xui/gnoll/status_right.png [new file with mode: 0755]
xui/gnoll/status_upper.png [new file with mode: 0755]
xui/gnoll/status_upper_left.png [new file with mode: 0755]
xui/gnoll/status_upper_right.png [new file with mode: 0755]
xui/gnoll/tiny_fill_bar_base.png [new file with mode: 0755]
xui/gnoll/tiny_fill_bar_left.png [new file with mode: 0755]
xui/gnoll/tiny_fill_bar_middle.png [new file with mode: 0755]
xui/gnoll/tiny_fill_bar_right.png [new file with mode: 0755]
xui/gnoll/title_bar_left.png [new file with mode: 0755]
xui/gnoll/title_bar_middle.png [new file with mode: 0755]
xui/gnoll/title_bar_right.png [new file with mode: 0755]
xui/gnoll/ubericon_frame.png [new file with mode: 0755]
xui/gnoll/window_left.png [new file with mode: 0755]
xui/gnoll/window_lower.png [new file with mode: 0755]
xui/gnoll/window_lower_left.png [new file with mode: 0755]
xui/gnoll/window_lower_right.png [new file with mode: 0755]
xui/gnoll/window_right.png [new file with mode: 0755]
xui/gnoll/window_upper.png [new file with mode: 0755]
xui/gnoll/window_upper_left.png [new file with mode: 0755]
xui/gnoll/window_upper_right.png [new file with mode: 0755]
xui/goblin/button_left.png [new file with mode: 0755]
xui/goblin/button_lower.png [new file with mode: 0755]
xui/goblin/button_lower_left.png [new file with mode: 0755]
xui/goblin/button_lower_right.png [new file with mode: 0755]
xui/goblin/button_middle.png [new file with mode: 0755]
xui/goblin/button_right.png [new file with mode: 0755]
xui/goblin/button_upper.png [new file with mode: 0755]
xui/goblin/button_upper_left.png [new file with mode: 0755]
xui/goblin/button_upper_right.png [new file with mode: 0755]
xui/goblin/check_box_off.png [new file with mode: 0755]
xui/goblin/check_box_on.png [new file with mode: 0755]
xui/goblin/cursor.png [new file with mode: 0755]
xui/goblin/end_turn_button.png [new file with mode: 0755]
xui/goblin/fill_bar_base.png [new file with mode: 0755]
xui/goblin/fill_bar_left.png [new file with mode: 0755]
xui/goblin/fill_bar_middle.png [new file with mode: 0755]
xui/goblin/fill_bar_right.png [new file with mode: 0755]
xui/goblin/frame_left.png [new file with mode: 0755]
xui/goblin/frame_lower.png [new file with mode: 0755]
xui/goblin/frame_lower_left.png [new file with mode: 0755]
xui/goblin/frame_lower_right.png [new file with mode: 0755]
xui/goblin/frame_right.png [new file with mode: 0755]
xui/goblin/frame_upper.png [new file with mode: 0755]
xui/goblin/frame_upper_left.png [new file with mode: 0755]
xui/goblin/frame_upper_right.png [new file with mode: 0755]
xui/goblin/icon_frame.png [new file with mode: 0755]
xui/goblin/menu_left.png [new file with mode: 0755]
xui/goblin/menu_lower.png [new file with mode: 0755]
xui/goblin/menu_lower_left.png [new file with mode: 0755]
xui/goblin/menu_lower_right.png [new file with mode: 0755]
xui/goblin/menu_middle.png [new file with mode: 0755]
xui/goblin/menu_right.png [new file with mode: 0755]
xui/goblin/menu_upper.png [new file with mode: 0755]
xui/goblin/menu_upper_left.png [new file with mode: 0755]
xui/goblin/menu_upper_right.png [new file with mode: 0755]
xui/goblin/overicon_frame.png [new file with mode: 0755]
xui/goblin/scroll_bar_lower.png [new file with mode: 0755]
xui/goblin/scroll_bar_middle.png [new file with mode: 0755]
xui/goblin/scroll_bar_slider.png [new file with mode: 0755]
xui/goblin/scroll_bar_upper.png [new file with mode: 0755]
xui/goblin/separator_center.png [new file with mode: 0755]
xui/goblin/separator_left.png [new file with mode: 0755]
xui/goblin/separator_middle.png [new file with mode: 0755]
xui/goblin/separator_right.png [new file with mode: 0755]
xui/goblin/status_left.png [new file with mode: 0755]
xui/goblin/status_lower.png [new file with mode: 0755]
xui/goblin/status_lower_left.png [new file with mode: 0755]
xui/goblin/status_lower_right.png [new file with mode: 0755]
xui/goblin/status_middle.png [new file with mode: 0755]
xui/goblin/status_right.png [new file with mode: 0755]
xui/goblin/status_upper.png [new file with mode: 0755]
xui/goblin/status_upper_left.png [new file with mode: 0755]
xui/goblin/status_upper_right.png [new file with mode: 0755]
xui/goblin/tiny_fill_bar_base.png [new file with mode: 0755]
xui/goblin/tiny_fill_bar_left.png [new file with mode: 0755]
xui/goblin/tiny_fill_bar_middle.png [new file with mode: 0755]
xui/goblin/tiny_fill_bar_right.png [new file with mode: 0755]
xui/goblin/title_bar_left.png [new file with mode: 0755]
xui/goblin/title_bar_middle.png [new file with mode: 0755]
xui/goblin/title_bar_right.png [new file with mode: 0755]
xui/goblin/ubericon_frame.png [new file with mode: 0755]
xui/goblin/window_left.png [new file with mode: 0755]
xui/goblin/window_lower.png [new file with mode: 0755]
xui/goblin/window_lower_left.png [new file with mode: 0755]
xui/goblin/window_lower_right.png [new file with mode: 0755]
xui/goblin/window_right.png [new file with mode: 0755]
xui/goblin/window_upper.png [new file with mode: 0755]
xui/goblin/window_upper_left.png [new file with mode: 0755]
xui/goblin/window_upper_right.png [new file with mode: 0755]
xui/imp/button_left.png [new file with mode: 0755]
xui/imp/button_lower.png [new file with mode: 0755]
xui/imp/button_lower_left.png [new file with mode: 0755]
xui/imp/button_lower_right.png [new file with mode: 0755]
xui/imp/button_middle.png [new file with mode: 0755]
xui/imp/button_right.png [new file with mode: 0755]
xui/imp/button_upper.png [new file with mode: 0755]
xui/imp/button_upper_left.png [new file with mode: 0755]
xui/imp/button_upper_right.png [new file with mode: 0755]
xui/imp/check_box_off.png [new file with mode: 0755]
xui/imp/check_box_on.png [new file with mode: 0755]
xui/imp/cursor.png [new file with mode: 0755]
xui/imp/end_turn_button.png [new file with mode: 0755]
xui/imp/fill_bar_base.png [new file with mode: 0755]
xui/imp/fill_bar_left.png [new file with mode: 0755]
xui/imp/fill_bar_middle.png [new file with mode: 0755]
xui/imp/fill_bar_right.png [new file with mode: 0755]
xui/imp/frame_left.png [new file with mode: 0755]
xui/imp/frame_lower.png [new file with mode: 0755]
xui/imp/frame_lower_left.png [new file with mode: 0755]
xui/imp/frame_lower_right.png [new file with mode: 0755]
xui/imp/frame_right.png [new file with mode: 0755]
xui/imp/frame_upper.png [new file with mode: 0755]
xui/imp/frame_upper_left.png [new file with mode: 0755]
xui/imp/frame_upper_right.png [new file with mode: 0755]
xui/imp/icon_frame.png [new file with mode: 0755]
xui/imp/menu_left.png [new file with mode: 0755]
xui/imp/menu_lower.png [new file with mode: 0755]
xui/imp/menu_lower_left.png [new file with mode: 0755]
xui/imp/menu_lower_right.png [new file with mode: 0755]
xui/imp/menu_middle.png [new file with mode: 0755]
xui/imp/menu_right.png [new file with mode: 0755]
xui/imp/menu_upper.png [new file with mode: 0755]
xui/imp/menu_upper_left.png [new file with mode: 0755]
xui/imp/menu_upper_right.png [new file with mode: 0755]
xui/imp/overicon_frame.png [new file with mode: 0755]
xui/imp/scroll_bar_lower.png [new file with mode: 0755]
xui/imp/scroll_bar_middle.png [new file with mode: 0755]
xui/imp/scroll_bar_slider.png [new file with mode: 0644]
xui/imp/scroll_bar_upper.png [new file with mode: 0755]
xui/imp/separator_center.png [new file with mode: 0644]
xui/imp/separator_left.png [new file with mode: 0755]
xui/imp/separator_middle.png [new file with mode: 0755]
xui/imp/separator_right.png [new file with mode: 0755]
xui/imp/status_left.png [new file with mode: 0755]
xui/imp/status_lower.png [new file with mode: 0755]
xui/imp/status_lower_left.png [new file with mode: 0755]
xui/imp/status_lower_right.png [new file with mode: 0755]
xui/imp/status_middle.png [new file with mode: 0755]
xui/imp/status_right.png [new file with mode: 0755]
xui/imp/status_upper.png [new file with mode: 0755]
xui/imp/status_upper_left.png [new file with mode: 0755]
xui/imp/status_upper_right.png [new file with mode: 0755]
xui/imp/tiny_fill_bar_base.png [new file with mode: 0755]
xui/imp/tiny_fill_bar_left.png [new file with mode: 0755]
xui/imp/tiny_fill_bar_middle.png [new file with mode: 0755]
xui/imp/tiny_fill_bar_right.png [new file with mode: 0755]
xui/imp/title_bar_left.png [new file with mode: 0755]
xui/imp/title_bar_middle.png [new file with mode: 0755]
xui/imp/title_bar_right.png [new file with mode: 0755]
xui/imp/ubericon_frame.png [new file with mode: 0755]
xui/imp/window_left.png [new file with mode: 0755]
xui/imp/window_lower.png [new file with mode: 0755]
xui/imp/window_lower_left.png [new file with mode: 0755]
xui/imp/window_lower_right.png [new file with mode: 0755]
xui/imp/window_right.png [new file with mode: 0755]
xui/imp/window_upper.png [new file with mode: 0755]
xui/imp/window_upper_left.png [new file with mode: 0755]
xui/imp/window_upper_right.png [new file with mode: 0755]
xui/kobold/button_left.png [new file with mode: 0755]
xui/kobold/button_lower.png [new file with mode: 0755]
xui/kobold/button_lower_left.png [new file with mode: 0755]
xui/kobold/button_lower_right.png [new file with mode: 0755]
xui/kobold/button_middle.png [new file with mode: 0755]
xui/kobold/button_right.png [new file with mode: 0755]
xui/kobold/button_upper.png [new file with mode: 0755]
xui/kobold/button_upper_left.png [new file with mode: 0755]
xui/kobold/button_upper_right.png [new file with mode: 0755]
xui/kobold/check_box_off.png [new file with mode: 0755]
xui/kobold/check_box_on.png [new file with mode: 0755]
xui/kobold/cursor.png [new file with mode: 0755]
xui/kobold/end_turn_button.png [new file with mode: 0755]
xui/kobold/fill_bar_base.png [new file with mode: 0755]
xui/kobold/fill_bar_left.png [new file with mode: 0755]
xui/kobold/fill_bar_middle.png [new file with mode: 0755]
xui/kobold/fill_bar_right.png [new file with mode: 0755]
xui/kobold/frame_left.png [new file with mode: 0755]
xui/kobold/frame_lower.png [new file with mode: 0755]
xui/kobold/frame_lower_left.png [new file with mode: 0755]
xui/kobold/frame_lower_right.png [new file with mode: 0755]
xui/kobold/frame_right.png [new file with mode: 0755]
xui/kobold/frame_upper.png [new file with mode: 0755]
xui/kobold/frame_upper_left.png [new file with mode: 0755]
xui/kobold/frame_upper_right.png [new file with mode: 0755]
xui/kobold/icon_frame.png [new file with mode: 0755]
xui/kobold/menu_left.png [new file with mode: 0755]
xui/kobold/menu_lower.png [new file with mode: 0755]
xui/kobold/menu_lower_left.png [new file with mode: 0755]
xui/kobold/menu_lower_right.png [new file with mode: 0755]
xui/kobold/menu_middle.png [new file with mode: 0755]
xui/kobold/menu_right.png [new file with mode: 0755]
xui/kobold/menu_upper.png [new file with mode: 0755]
xui/kobold/menu_upper_left.png [new file with mode: 0755]
xui/kobold/menu_upper_right.png [new file with mode: 0755]
xui/kobold/overicon_frame.png [new file with mode: 0755]
xui/kobold/scroll_bar_lower.png [new file with mode: 0755]
xui/kobold/scroll_bar_middle.png [new file with mode: 0755]
xui/kobold/scroll_bar_slider.png [new file with mode: 0755]
xui/kobold/scroll_bar_upper.png [new file with mode: 0755]
xui/kobold/separator_center.png [new file with mode: 0755]
xui/kobold/separator_left.png [new file with mode: 0755]
xui/kobold/separator_middle.png [new file with mode: 0755]
xui/kobold/separator_right.png [new file with mode: 0755]
xui/kobold/status_left.png [new file with mode: 0755]
xui/kobold/status_lower.png [new file with mode: 0755]
xui/kobold/status_lower_left.png [new file with mode: 0755]
xui/kobold/status_lower_right.png [new file with mode: 0755]
xui/kobold/status_middle.png [new file with mode: 0755]
xui/kobold/status_right.png [new file with mode: 0755]
xui/kobold/status_upper.png [new file with mode: 0755]
xui/kobold/status_upper_left.png [new file with mode: 0755]
xui/kobold/status_upper_right.png [new file with mode: 0755]
xui/kobold/tiny_fill_bar_base.png [new file with mode: 0755]
xui/kobold/tiny_fill_bar_left.png [new file with mode: 0755]
xui/kobold/tiny_fill_bar_middle.png [new file with mode: 0755]
xui/kobold/tiny_fill_bar_right.png [new file with mode: 0755]
xui/kobold/title_bar_left.png [new file with mode: 0755]
xui/kobold/title_bar_middle.png [new file with mode: 0755]
xui/kobold/title_bar_right.png [new file with mode: 0755]
xui/kobold/ubericon_frame.png [new file with mode: 0755]
xui/kobold/window_left.png [new file with mode: 0755]
xui/kobold/window_lower.png [new file with mode: 0755]
xui/kobold/window_lower_left.png [new file with mode: 0755]
xui/kobold/window_lower_right.png [new file with mode: 0755]
xui/kobold/window_right.png [new file with mode: 0755]
xui/kobold/window_upper.png [new file with mode: 0755]
xui/kobold/window_upper_left.png [new file with mode: 0755]
xui/kobold/window_upper_right.png [new file with mode: 0755]
xui/main/button_left.png [new file with mode: 0755]
xui/main/button_lower.png [new file with mode: 0755]
xui/main/button_lower_left.png [new file with mode: 0755]
xui/main/button_lower_right.png [new file with mode: 0755]
xui/main/button_middle.png [new file with mode: 0755]
xui/main/button_right.png [new file with mode: 0755]
xui/main/button_upper.png [new file with mode: 0755]
xui/main/button_upper_left.png [new file with mode: 0755]
xui/main/button_upper_right.png [new file with mode: 0755]
xui/main/check_box_off.png [new file with mode: 0755]
xui/main/check_box_on.png [new file with mode: 0755]
xui/main/cursor.png [new file with mode: 0755]
xui/main/end_turn_button.png [new file with mode: 0755]
xui/main/fill_bar_base.png [new file with mode: 0755]
xui/main/fill_bar_left.png [new file with mode: 0755]
xui/main/fill_bar_middle.png [new file with mode: 0755]
xui/main/fill_bar_right.png [new file with mode: 0755]
xui/main/frame_left.png [new file with mode: 0755]
xui/main/frame_lower.png [new file with mode: 0755]
xui/main/frame_lower_left.png [new file with mode: 0755]
xui/main/frame_lower_right.png [new file with mode: 0755]
xui/main/frame_right.png [new file with mode: 0755]
xui/main/frame_upper.png [new file with mode: 0755]
xui/main/frame_upper_left.png [new file with mode: 0755]
xui/main/frame_upper_right.png [new file with mode: 0755]
xui/main/icon_frame.png [new file with mode: 0755]
xui/main/menu_left.png [new file with mode: 0755]
xui/main/menu_lower.png [new file with mode: 0755]
xui/main/menu_lower_left.png [new file with mode: 0755]
xui/main/menu_lower_right.png [new file with mode: 0755]
xui/main/menu_middle.png [new file with mode: 0755]
xui/main/menu_right.png [new file with mode: 0755]
xui/main/menu_upper.png [new file with mode: 0755]
xui/main/menu_upper_left.png [new file with mode: 0755]
xui/main/menu_upper_right.png [new file with mode: 0755]
xui/main/overicon_frame.png [new file with mode: 0755]
xui/main/scroll_bar_lower.png [new file with mode: 0755]
xui/main/scroll_bar_middle.png [new file with mode: 0755]
xui/main/scroll_bar_slider.png [new file with mode: 0755]
xui/main/scroll_bar_upper.png [new file with mode: 0755]
xui/main/separator_center.png [new file with mode: 0755]
xui/main/separator_left.png [new file with mode: 0755]
xui/main/separator_middle.png [new file with mode: 0755]
xui/main/separator_right.png [new file with mode: 0755]
xui/main/status_left.png [new file with mode: 0755]
xui/main/status_lower.png [new file with mode: 0755]
xui/main/status_lower_left.png [new file with mode: 0755]
xui/main/status_lower_right.png [new file with mode: 0755]
xui/main/status_middle.png [new file with mode: 0755]
xui/main/status_right.png [new file with mode: 0755]
xui/main/status_upper.png [new file with mode: 0755]
xui/main/status_upper_left.png [new file with mode: 0755]
xui/main/status_upper_right.png [new file with mode: 0755]
xui/main/tiny_fill_bar_base.png [new file with mode: 0755]
xui/main/tiny_fill_bar_left.png [new file with mode: 0755]
xui/main/tiny_fill_bar_middle.png [new file with mode: 0755]
xui/main/tiny_fill_bar_right.png [new file with mode: 0755]
xui/main/title_bar_left.png [new file with mode: 0755]
xui/main/title_bar_middle.png [new file with mode: 0755]
xui/main/title_bar_right.png [new file with mode: 0755]
xui/main/ubericon_frame.png [new file with mode: 0755]
xui/main/window_left.png [new file with mode: 0755]
xui/main/window_lower.png [new file with mode: 0755]
xui/main/window_lower_left.png [new file with mode: 0755]
xui/main/window_lower_right.png [new file with mode: 0755]
xui/main/window_right.png [new file with mode: 0755]
xui/main/window_upper.png [new file with mode: 0755]
xui/main/window_upper_left.png [new file with mode: 0755]
xui/main/window_upper_right.png [new file with mode: 0755]
xui/map_preview_panel_off.png [new file with mode: 0755]
xui/map_preview_panel_on.png [new file with mode: 0755]
xui/monospace.png [new file with mode: 0755]
xui/palette.png [new file with mode: 0755]
xui/regular.png [new file with mode: 0755]
xui/status_preview_panel_off.png [new file with mode: 0755]
xui/status_preview_panel_on.png [new file with mode: 0755]
xui/text_box_panel_off.png [new file with mode: 0755]
xui/text_box_panel_on.png [new file with mode: 0755]
xulkan.h [new file with mode: 0755]
xungeon.h [new file with mode: 0755]
xuxuxu.c [new file with mode: 0755]
xyntax.h [new file with mode: 0755]

diff --git a/.gitignore b/.gitignore
new file mode 100755 (executable)
index 0000000..906d731
--- /dev/null
@@ -0,0 +1,8 @@
+xop
+xscii
+xtatus
+xighlight
+xhallenge
+xuxuxu
+xarbon
+xource
diff --git a/LICENSE b/LICENSE
new file mode 100755 (executable)
index 0000000..e142a52
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,625 @@
+GNU GENERAL PUBLIC LICENSE
+
+Version 3, 29 June 2007
+
+Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The GNU General Public License is a free, copyleft license for software and
+other kinds of works.
+
+The licenses for most software and other practical works are designed to take
+away your freedom to share and change the works. By contrast, the GNU General
+Public License is intended to guarantee your freedom to share and change all
+versions of a program--to make sure it remains free software for all its users.
+We, the Free Software Foundation, use the GNU General Public License for most
+of our software; it applies also to any other work released this way by its
+authors. You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom
+to distribute copies of free software (and charge for them if you wish), that
+you receive source code or can get it if you want it, that you can change
+the software or use pieces of it in new free programs, and that you know you
+can do these things.
+
+To protect your rights, we need to prevent others from denying you these rights
+or asking you to surrender the rights. Therefore, you have certain responsibilities
+if you distribute copies of the software, or if you modify it: responsibilities
+to respect the freedom of others.
+
+For example, if you distribute copies of such a program, whether gratis or
+for a fee, you must pass on to the recipients the same freedoms that you received.
+You must make sure that they, too, receive or can get the source code. And
+you must show them these terms so they know their rights.
+
+Developers that use the GNU GPL protect your rights with two steps: (1) assert
+copyright on the software, and (2) offer you this License giving you legal
+permission to copy, distribute and/or modify it.
+
+For the developers' and authors' protection, the GPL clearly explains that
+there is no warranty for this free software. For both users' and authors'
+sake, the GPL requires that modified versions be marked as changed, so that
+their problems will not be attributed erroneously to authors of previous versions.
+
+Some devices are designed to deny users access to install or run modified
+versions of the software inside them, although the manufacturer can do so.
+This is fundamentally incompatible with the aim of protecting users' freedom
+to change the software. The systematic pattern of such abuse occurs in the
+area of products for individuals to use, which is precisely where it is most
+unacceptable. Therefore, we have designed this version of the GPL to prohibit
+the practice for those products. If such problems arise substantially in other
+domains, we stand ready to extend this provision to those domains in future
+versions of the GPL, as needed to protect the freedom of users.
+
+Finally, every program is threatened constantly by software patents. States
+should not allow patents to restrict development and use of software on general-purpose
+computers, but in those that do, we wish to avoid the special danger that
+patents applied to a free program could make it effectively proprietary. To
+prevent this, the GPL assures that patents cannot be used to render the program
+non-free.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS
+
+   0. Definitions.
+
+   "This License" refers to version 3 of the GNU General Public License.
+
+"Copyright" also means copyright-like laws that apply to other kinds of works,
+such as semiconductor masks.
+
+"The Program" refers to any copyrightable work licensed under this License.
+Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals
+or organizations.
+
+To "modify" a work means to copy from or adapt all or part of the work in
+a fashion requiring copyright permission, other than the making of an exact
+copy. The resulting work is called a "modified version" of the earlier work
+or a work "based on" the earlier work.
+
+A "covered work" means either the unmodified Program or a work based on the
+Program.
+
+To "propagate" a work means to do anything with it that, without permission,
+would make you directly or secondarily liable for infringement under applicable
+copyright law, except executing it on a computer or modifying a private copy.
+Propagation includes copying, distribution (with or without modification),
+making available to the public, and in some countries other activities as
+well.
+
+To "convey" a work means any kind of propagation that enables other parties
+to make or receive copies. Mere interaction with a user through a computer
+network, with no transfer of a copy, is not conveying.
+
+An interactive user interface displays "Appropriate Legal Notices" to the
+extent that it includes a convenient and prominently visible feature that
+(1) displays an appropriate copyright notice, and (2) tells the user that
+there is no warranty for the work (except to the extent that warranties are
+provided), that licensees may convey the work under this License, and how
+to view a copy of this License. If the interface presents a list of user commands
+or options, such as a menu, a prominent item in the list meets this criterion.
+
+   1. Source Code.
+
+The "source code" for a work means the preferred form of the work for making
+modifications to it. "Object code" means any non-source form of a work.
+
+A "Standard Interface" means an interface that either is an official standard
+defined by a recognized standards body, or, in the case of interfaces specified
+for a particular programming language, one that is widely used among developers
+working in that language.
+
+The "System Libraries" of an executable work include anything, other than
+the work as a whole, that (a) is included in the normal form of packaging
+a Major Component, but which is not part of that Major Component, and (b)
+serves only to enable use of the work with that Major Component, or to implement
+a Standard Interface for which an implementation is available to the public
+in source code form. A "Major Component", in this context, means a major essential
+component (kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to produce
+the work, or an object code interpreter used to run it.
+
+The "Corresponding Source" for a work in object code form means all the source
+code needed to generate, install, and (for an executable work) run the object
+code and to modify the work, including scripts to control those activities.
+However, it does not include the work's System Libraries, or general-purpose
+tools or generally available free programs which are used unmodified in performing
+those activities but which are not part of the work. For example, Corresponding
+Source includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically linked
+subprograms that the work is specifically designed to require, such as by
+intimate data communication or control flow between those subprograms and
+other parts of the work.
+
+The Corresponding Source need not include anything that users can regenerate
+automatically from other parts of the Corresponding Source.
+
+   The Corresponding Source for a work in source code form is that same work.
+
+   2. Basic Permissions.
+
+All rights granted under this License are granted for the term of copyright
+on the Program, and are irrevocable provided the stated conditions are met.
+This License explicitly affirms your unlimited permission to run the unmodified
+Program. The output from running a covered work is covered by this License
+only if the output, given its content, constitutes a covered work. This License
+acknowledges your rights of fair use or other equivalent, as provided by copyright
+law.
+
+You may make, run and propagate covered works that you do not convey, without
+conditions so long as your license otherwise remains in force. You may convey
+covered works to others for the sole purpose of having them make modifications
+exclusively for you, or provide you with facilities for running those works,
+provided that you comply with the terms of this License in conveying all material
+for which you do not control copyright. Those thus making or running the covered
+works for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of your copyrighted
+material outside their relationship with you.
+
+Conveying under any other circumstances is permitted solely under the conditions
+stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
+
+   3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+No covered work shall be deemed part of an effective technological measure
+under any applicable law fulfilling obligations under article 11 of the WIPO
+copyright treaty adopted on 20 December 1996, or similar laws prohibiting
+or restricting circumvention of such measures.
+
+When you convey a covered work, you waive any legal power to forbid circumvention
+of technological measures to the extent such circumvention is effected by
+exercising rights under this License with respect to the covered work, and
+you disclaim any intention to limit operation or modification of the work
+as a means of enforcing, against the work's users, your or third parties'
+legal rights to forbid circumvention of technological measures.
+
+   4. Conveying Verbatim Copies.
+
+You may convey verbatim copies of the Program's source code as you receive
+it, in any medium, provided that you conspicuously and appropriately publish
+on each copy an appropriate copyright notice; keep intact all notices stating
+that this License and any non-permissive terms added in accord with section
+7 apply to the code; keep intact all notices of the absence of any warranty;
+and give all recipients a copy of this License along with the Program.
+
+You may charge any price or no price for each copy that you convey, and you
+may offer support or warranty protection for a fee.
+
+   5. Conveying Modified Source Versions.
+
+You may convey a work based on the Program, or the modifications to produce
+it from the Program, in the form of source code under the terms of section
+4, provided that you also meet all of these conditions:
+
+a) The work must carry prominent notices stating that you modified it, and
+giving a relevant date.
+
+b) The work must carry prominent notices stating that it is released under
+this License and any conditions added under section 7. This requirement modifies
+the requirement in section 4 to "keep intact all notices".
+
+c) You must license the entire work, as a whole, under this License to anyone
+who comes into possession of a copy. This License will therefore apply, along
+with any applicable section 7 additional terms, to the whole of the work,
+and all its parts, regardless of how they are packaged. This License gives
+no permission to license the work in any other way, but it does not invalidate
+such permission if you have separately received it.
+
+d) If the work has interactive user interfaces, each must display Appropriate
+Legal Notices; however, if the Program has interactive interfaces that do
+not display Appropriate Legal Notices, your work need not make them do so.
+
+A compilation of a covered work with other separate and independent works,
+which are not by their nature extensions of the covered work, and which are
+not combined with it such as to form a larger program, in or on a volume of
+a storage or distribution medium, is called an "aggregate" if the compilation
+and its resulting copyright are not used to limit the access or legal rights
+of the compilation's users beyond what the individual works permit. Inclusion
+of a covered work in an aggregate does not cause this License to apply to
+the other parts of the aggregate.
+
+   6. Conveying Non-Source Forms.
+
+You may convey a covered work in object code form under the terms of sections
+4 and 5, provided that you also convey the machine-readable Corresponding
+Source under the terms of this License, in one of these ways:
+
+a) Convey the object code in, or embodied in, a physical product (including
+a physical distribution medium), accompanied by the Corresponding Source fixed
+on a durable physical medium customarily used for software interchange.
+
+b) Convey the object code in, or embodied in, a physical product (including
+a physical distribution medium), accompanied by a written offer, valid for
+at least three years and valid for as long as you offer spare parts or customer
+support for that product model, to give anyone who possesses the object code
+either (1) a copy of the Corresponding Source for all the software in the
+product that is covered by this License, on a durable physical medium customarily
+used for software interchange, for a price no more than your reasonable cost
+of physically performing this conveying of source, or (2) access to copy the
+Corresponding Source from a network server at no charge.
+
+c) Convey individual copies of the object code with a copy of the written
+offer to provide the Corresponding Source. This alternative is allowed only
+occasionally and noncommercially, and only if you received the object code
+with such an offer, in accord with subsection 6b.
+
+d) Convey the object code by offering access from a designated place (gratis
+or for a charge), and offer equivalent access to the Corresponding Source
+in the same way through the same place at no further charge. You need not
+require recipients to copy the Corresponding Source along with the object
+code. If the place to copy the object code is a network server, the Corresponding
+Source may be on a different server (operated by you or a third party) that
+supports equivalent copying facilities, provided you maintain clear directions
+next to the object code saying where to find the Corresponding Source. Regardless
+of what server hosts the Corresponding Source, you remain obligated to ensure
+that it is available for as long as needed to satisfy these requirements.
+
+e) Convey the object code using peer-to-peer transmission, provided you inform
+other peers where the object code and Corresponding Source of the work are
+being offered to the general public at no charge under subsection 6d.
+
+A separable portion of the object code, whose source code is excluded from
+the Corresponding Source as a System Library, need not be included in conveying
+the object code work.
+
+A "User Product" is either (1) a "consumer product", which means any tangible
+personal property which is normally used for personal, family, or household
+purposes, or (2) anything designed or sold for incorporation into a dwelling.
+In determining whether a product is a consumer product, doubtful cases shall
+be resolved in favor of coverage. For a particular product received by a particular
+user, "normally used" refers to a typical or common use of that class of product,
+regardless of the status of the particular user or of the way in which the
+particular user actually uses, or expects or is expected to use, the product.
+A product is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent the
+only significant mode of use of the product.
+
+"Installation Information" for a User Product means any methods, procedures,
+authorization keys, or other information required to install and execute modified
+versions of a covered work in that User Product from a modified version of
+its Corresponding Source. The information must suffice to ensure that the
+continued functioning of the modified object code is in no case prevented
+or interfered with solely because modification has been made.
+
+If you convey an object code work under this section in, or with, or specifically
+for use in, a User Product, and the conveying occurs as part of a transaction
+in which the right of possession and use of the User Product is transferred
+to the recipient in perpetuity or for a fixed term (regardless of how the
+transaction is characterized), the Corresponding Source conveyed under this
+section must be accompanied by the Installation Information. But this requirement
+does not apply if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has been installed
+in ROM).
+
+The requirement to provide Installation Information does not include a requirement
+to continue to provide support service, warranty, or updates for a work that
+has been modified or installed by the recipient, or for the User Product in
+which it has been modified or installed. Access to a network may be denied
+when the modification itself materially and adversely affects the operation
+of the network or violates the rules and protocols for communication across
+the network.
+
+Corresponding Source conveyed, and Installation Information provided, in accord
+with this section must be in a format that is publicly documented (and with
+an implementation available to the public in source code form), and must require
+no special password or key for unpacking, reading or copying.
+
+   7. Additional Terms.
+
+"Additional permissions" are terms that supplement the terms of this License
+by making exceptions from one or more of its conditions. Additional permissions
+that are applicable to the entire Program shall be treated as though they
+were included in this License, to the extent that they are valid under applicable
+law. If additional permissions apply only to part of the Program, that part
+may be used separately under those permissions, but the entire Program remains
+governed by this License without regard to the additional permissions.
+
+When you convey a copy of a covered work, you may at your option remove any
+additional permissions from that copy, or from any part of it. (Additional
+permissions may be written to require their own removal in certain cases when
+you modify the work.) You may place additional permissions on material, added
+by you to a covered work, for which you have or can give appropriate copyright
+permission.
+
+Notwithstanding any other provision of this License, for material you add
+to a covered work, you may (if authorized by the copyright holders of that
+material) supplement the terms of this License with terms:
+
+a) Disclaiming warranty or limiting liability differently from the terms of
+sections 15 and 16 of this License; or
+
+b) Requiring preservation of specified reasonable legal notices or author
+attributions in that material or in the Appropriate Legal Notices displayed
+by works containing it; or
+
+c) Prohibiting misrepresentation of the origin of that material, or requiring
+that modified versions of such material be marked in reasonable ways as different
+from the original version; or
+
+d) Limiting the use for publicity purposes of names of licensors or authors
+of the material; or
+
+e) Declining to grant rights under trademark law for use of some trade names,
+trademarks, or service marks; or
+
+f) Requiring indemnification of licensors and authors of that material by
+anyone who conveys the material (or modified versions of it) with contractual
+assumptions of liability to the recipient, for any liability that these contractual
+assumptions directly impose on those licensors and authors.
+
+All other non-permissive additional terms are considered "further restrictions"
+within the meaning of section 10. If the Program as you received it, or any
+part of it, contains a notice stating that it is governed by this License
+along with a term that is a further restriction, you may remove that term.
+If a license document contains a further restriction but permits relicensing
+or conveying under this License, you may add to a covered work material governed
+by the terms of that license document, provided that the further restriction
+does not survive such relicensing or conveying.
+
+If you add terms to a covered work in accord with this section, you must place,
+in the relevant source files, a statement of the additional terms that apply
+to those files, or a notice indicating where to find the applicable terms.
+
+Additional terms, permissive or non-permissive, may be stated in the form
+of a separately written license, or stated as exceptions; the above requirements
+apply either way.
+
+   8. Termination.
+
+You may not propagate or modify a covered work except as expressly provided
+under this License. Any attempt otherwise to propagate or modify it is void,
+and will automatically terminate your rights under this License (including
+any patent licenses granted under the third paragraph of section 11).
+
+However, if you cease all violation of this License, then your license from
+a particular copyright holder is reinstated (a) provisionally, unless and
+until the copyright holder explicitly and finally terminates your license,
+and (b) permanently, if the copyright holder fails to notify you of the violation
+by some reasonable means prior to 60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is reinstated permanently
+if the copyright holder notifies you of the violation by some reasonable means,
+this is the first time you have received notice of violation of this License
+(for any work) from that copyright holder, and you cure the violation prior
+to 30 days after your receipt of the notice.
+
+Termination of your rights under this section does not terminate the licenses
+of parties who have received copies or rights from you under this License.
+If your rights have been terminated and not permanently reinstated, you do
+not qualify to receive new licenses for the same material under section 10.
+
+   9. Acceptance Not Required for Having Copies.
+
+You are not required to accept this License in order to receive or run a copy
+of the Program. Ancillary propagation of a covered work occurring solely as
+a consequence of using peer-to-peer transmission to receive a copy likewise
+does not require acceptance. However, nothing other than this License grants
+you permission to propagate or modify any covered work. These actions infringe
+copyright if you do not accept this License. Therefore, by modifying or propagating
+a covered work, you indicate your acceptance of this License to do so.
+
+   10. Automatic Licensing of Downstream Recipients.
+
+Each time you convey a covered work, the recipient automatically receives
+a license from the original licensors, to run, modify and propagate that work,
+subject to this License. You are not responsible for enforcing compliance
+by third parties with this License.
+
+An "entity transaction" is a transaction transferring control of an organization,
+or substantially all assets of one, or subdividing an organization, or merging
+organizations. If propagation of a covered work results from an entity transaction,
+each party to that transaction who receives a copy of the work also receives
+whatever licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the Corresponding
+Source of the work from the predecessor in interest, if the predecessor has
+it or can get it with reasonable efforts.
+
+You may not impose any further restrictions on the exercise of the rights
+granted or affirmed under this License. For example, you may not impose a
+license fee, royalty, or other charge for exercise of rights granted under
+this License, and you may not initiate litigation (including a cross-claim
+or counterclaim in a lawsuit) alleging that any patent claim is infringed
+by making, using, selling, offering for sale, or importing the Program or
+any portion of it.
+
+   11. Patents.
+
+A "contributor" is a copyright holder who authorizes use under this License
+of the Program or a work on which the Program is based. The work thus licensed
+is called the contributor's "contributor version".
+
+A contributor's "essential patent claims" are all patent claims owned or controlled
+by the contributor, whether already acquired or hereafter acquired, that would
+be infringed by some manner, permitted by this License, of making, using,
+or selling its contributor version, but do not include claims that would be
+infringed only as a consequence of further modification of the contributor
+version. For purposes of this definition, "control" includes the right to
+grant patent sublicenses in a manner consistent with the requirements of this
+License.
+
+Each contributor grants you a non-exclusive, worldwide, royalty-free patent
+license under the contributor's essential patent claims, to make, use, sell,
+offer for sale, import and otherwise run, modify and propagate the contents
+of its contributor version.
+
+In the following three paragraphs, a "patent license" is any express agreement
+or commitment, however denominated, not to enforce a patent (such as an express
+permission to practice a patent or covenant not to sue for patent infringement).
+To "grant" such a patent license to a party means to make such an agreement
+or commitment not to enforce a patent against the party.
+
+If you convey a covered work, knowingly relying on a patent license, and the
+Corresponding Source of the work is not available for anyone to copy, free
+of charge and under the terms of this License, through a publicly available
+network server or other readily accessible means, then you must either (1)
+cause the Corresponding Source to be so available, or (2) arrange to deprive
+yourself of the benefit of the patent license for this particular work, or
+(3) arrange, in a manner consistent with the requirements of this License,
+to extend the patent license to downstream recipients. "Knowingly relying"
+means you have actual knowledge that, but for the patent license, your conveying
+the covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that country
+that you have reason to believe are valid.
+
+If, pursuant to or in connection with a single transaction or arrangement,
+you convey, or propagate by procuring conveyance of, a covered work, and grant
+a patent license to some of the parties receiving the covered work authorizing
+them to use, propagate, modify or convey a specific copy of the covered work,
+then the patent license you grant is automatically extended to all recipients
+of the covered work and works based on it.
+
+A patent license is "discriminatory" if it does not include within the scope
+of its coverage, prohibits the exercise of, or is conditioned on the non-exercise
+of one or more of the rights that are specifically granted under this License.
+You may not convey a covered work if you are a party to an arrangement with
+a third party that is in the business of distributing software, under which
+you make payment to the third party based on the extent of your activity of
+conveying the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory patent
+license (a) in connection with copies of the covered work conveyed by you
+(or copies made from those copies), or (b) primarily for and in connection
+with specific products or compilations that contain the covered work, unless
+you entered into that arrangement, or that patent license was granted, prior
+to 28 March 2007.
+
+Nothing in this License shall be construed as excluding or limiting any implied
+license or other defenses to infringement that may otherwise be available
+to you under applicable patent law.
+
+   12. No Surrender of Others' Freedom.
+
+If conditions are imposed on you (whether by court order, agreement or otherwise)
+that contradict the conditions of this License, they do not excuse you from
+the conditions of this License. If you cannot convey a covered work so as
+to satisfy simultaneously your obligations under this License and any other
+pertinent obligations, then as a consequence you may not convey it at all.
+For example, if you agree to terms that obligate you to collect a royalty
+for further conveying from those to whom you convey the Program, the only
+way you could satisfy both those terms and this License would be to refrain
+entirely from conveying the Program.
+
+   13. Use with the GNU Affero General Public License.
+
+Notwithstanding any other provision of this License, you have permission to
+link or combine any covered work with a work licensed under version 3 of the
+GNU Affero General Public License into a single combined work, and to convey
+the resulting work. The terms of this License will continue to apply to the
+part which is the covered work, but the special requirements of the GNU Affero
+General Public License, section 13, concerning interaction through a network
+will apply to the combination as such.
+
+   14. Revised Versions of this License.
+
+The Free Software Foundation may publish revised and/or new versions of the
+GNU General Public License from time to time. Such new versions will be similar
+in spirit to the present version, but may differ in detail to address new
+problems or concerns.
+
+Each version is given a distinguishing version number. If the Program specifies
+that a certain numbered version of the GNU General Public License "or any
+later version" applies to it, you have the option of following the terms and
+conditions either of that numbered version or of any later version published
+by the Free Software Foundation. If the Program does not specify a version
+number of the GNU General Public License, you may choose any version ever
+published by the Free Software Foundation.
+
+If the Program specifies that a proxy can decide which future versions of
+the GNU General Public License can be used, that proxy's public statement
+of acceptance of a version permanently authorizes you to choose that version
+for the Program.
+
+Later license versions may give you additional or different permissions. However,
+no additional obligations are imposed on any author or copyright holder as
+a result of your choosing to follow a later version.
+
+   15. Disclaimer of Warranty.
+
+THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
+LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
+PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+   16. Limitation of Liability.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM
+AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
+INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO
+USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
+PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
+PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+   17. Interpretation of Sections 15 and 16.
+
+If the disclaimer of warranty and limitation of liability provided above cannot
+be given local legal effect according to their terms, reviewing courts shall
+apply local law that most closely approximates an absolute waiver of all civil
+liability in connection with the Program, unless a warranty or assumption
+of liability accompanies a copy of the Program in return for a fee. END OF
+TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest to attach
+them to the start of each source file to most effectively state the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+<one line to give the program's name and a brief idea of what it does.>
+
+Copyright (C) <year> <name of author>
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program does terminal interaction, make it output a short notice like
+this when it starts in an interactive mode:
+
+<program> Copyright (C) <year> <name of author>
+
+This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+
+This is free software, and you are welcome to redistribute it under certain
+conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands might
+be different; for a GUI interface, you would use an "about box".
+
+You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary. For
+more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.
+
+The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General Public
+License instead of this License. But first, please read <https://www.gnu.org/
+licenses /why-not-lgpl.html>.
diff --git a/README.md b/README.md
new file mode 100755 (executable)
index 0000000..79789c2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,41 @@
+# xolatilization
+
+## xolatilization --- Collection of my undocumented libraries in single repository for easy installation after distro-hopping.
+
+This isn't like the usual compilation and installation method used in one-off repositories. You should run the 'install.sh' script first, so C
+header files are copied where they should be, then do the usual steps of running 'compile.sh' and 'install.sh', everything should be properly
+compiled and installed in that case. That's the sole reason of this comment.
+
+Compile: `$ sh compile.sh`
+
+Install: `$ sudo sh install.sh`
+
+Libraries:
+- `xtandard` --- Common functions in my programs with nice readable names.
+- `xrena` --- Arena allocator containing one big badass global variable.
+- `xyntax` --- General syntax definition for slow and easy parsing.
+- `xanguage` --- Evil definitions of various programming languages and more.
+- `xachine` --- Tiny Intel (IA32e) semi-32-bit only bytecode assembler.
+- `xiasma` --- Huge Intel (IA32e) 64-bit only selective bytecode assembler.
+- `xector` --- Linear algebra library for 2D, 3D and 4D vectors.
+- `xatrix` --- Linear algebra library for 2D, 3D and 4D matrices.
+- `xphere` --- Spherical coordinate system utility for ray tracing.
+- `xcript` --- Tiny INI-like script parser with extendable definition.
+- `xrocessor` --- Evil embeddable preprocessor Pascal-like syntax.
+- `xerminal` --- VT100 escape sequence shortcuts with 'ioctl' support.
+- `xommon` --- Sane and tiny XCB wrapper for graphical programs.
+- `xpengl` --- Sane and tiny OpenGL+GLFW wrapper for graphical programs.
+- `xulkan` --- Insane and huge XCB+Vulkan wrapper for graphical programs.
+- `xross` --- Wrapper for wrappers above for graphical programs.
+- `xpenal` --- Minimal wrapper for threaded OpenAL sound management.
+- `xprite` --- Dumb and small file format for storing indexed images.
+- `xormat` --- Containment for file formats I hate but have to use sadly.
+- `xui` --- UI library with predefined elements and offsets.
+
+Programs:
+- `xop` --- Retarded program for raw machine code debugging.
+- `xscii` --- Simple (not very) printing of readable ASCII table.
+- `xighlight` --- Highlight few languages and program outputs in terminal.
+- `xhallenge` --- Randomly generate daily challenges based on your attributes.
+- `xuxuxu` --- Terrence Andrew Davis tribute program to generate PNG image.
+- `xarbon` --- Carbon clone to render source code of few languages.
diff --git a/compile.sh b/compile.sh
new file mode 100755 (executable)
index 0000000..c2e2135
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+set -xe
+
+mkdir -p $HOME/.config/xolatile/
+mkdir -p $HOME/.config/xolatile/xui
+
+gcc -std=gnu99 -Wall -Wextra -Wpedantic -Werror -Ofast -o xop       xop.c
+gcc -std=gnu99 -Wall -Wextra -Wpedantic -Werror -Ofast -o xscii     xscii.c
+gcc -std=gnu99 -Wall -Wextra -Wpedantic -Werror -Ofast -o xighlight xighlight.c
+gcc -std=gnu99 -Wall -Wextra -Wpedantic -Werror -Ofast -o xhallenge xhallenge.c
+gcc -std=gnu99 -Wall -Wextra -Wpedantic -Werror -Ofast -o xuxuxu    xuxuxu.c    -lpng
+gcc -std=gnu99 -Wall -Wextra -Wpedantic -Werror -Ofast -o xarbon    xarbon.c    -lpng
+
+cp -f xhallenge_list.cfg $HOME/.config/xolatile/xhallenge_list.cfg
+
+cp -rf xui $HOME/.config/xolatile/
+
+exit
diff --git a/install.sh b/install.sh
new file mode 100755 (executable)
index 0000000..5ec3b17
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+set -xe
+
+mkdir -p /usr/local/include/xolatile
+
+cp -f xtandard.h /usr/local/include/xolatile/xtandard.h
+cp -f xrena.h    /usr/local/include/xolatile/xrena.h
+cp -f xyntax.h   /usr/local/include/xolatile/xyntax.h
+cp -f xanguage.h /usr/local/include/xolatile/xanguage.h
+cp -f xcript.h   /usr/local/include/xolatile/xcript.h
+cp -f xiasma.h   /usr/local/include/xolatile/xiasma.h
+cp -f xachine.h  /usr/local/include/xolatile/xachine.h
+cp -f xprite.h   /usr/local/include/xolatile/xprite.h
+cp -f xphere.h   /usr/local/include/xolatile/xphere.h
+cp -f xector.h   /usr/local/include/xolatile/xector.h
+cp -f xormat.h   /usr/local/include/xolatile/xormat.h
+cp -f xerminal.h /usr/local/include/xolatile/xerminal.h
+cp -f xaptor.h   /usr/local/include/xolatile/xaptor.h
+cp -f xommon.h   /usr/local/include/xolatile/xommon.h
+cp -f xpengl.h   /usr/local/include/xolatile/xpengl.h
+cp -f xross.h    /usr/local/include/xolatile/xross.h
+cp -f xui.h      /usr/local/include/xolatile/xui.h
+cp -f xungeon.h  /usr/local/include/xolatile/xungeon.h
+
+cp -rf xanguage /usr/local/include/xolatile/
+cp -rf xormat   /usr/local/include/xolatile/
+
+if [ -f xop ]; then
+       cp -f xop /usr/local/bin/xop
+fi
+
+if [ -f xscii ]; then
+       cp -f xscii /usr/local/bin/xscii
+fi
+
+if [ -f xighlight ]; then
+       cp -f xighlight /usr/local/bin/xighlight
+fi
+
+if [ -f xhallenge ]; then
+       cp -f xhallenge /usr/local/bin/xhallenge
+fi
+
+if [ -f xuxuxu ]; then
+       cp -f xuxuxu /usr/local/bin/xuxuxu
+fi
+
+if [ -f xarbon ]; then
+       cp -f xarbon /usr/local/bin/xarbon
+fi
+
+exit
diff --git a/test b/test
new file mode 100755 (executable)
index 0000000..7eae4d2
Binary files /dev/null and b/test differ
diff --git a/test.c b/test.c
new file mode 100644 (file)
index 0000000..8b241cb
--- /dev/null
+++ b/test.c
@@ -0,0 +1,79 @@
+#define use_mathematics
+
+#include "xtandard.h"
+#include "xector.h"
+#include "xarticle.h"
+
+#include <raylib.h>
+
+int main (void) {
+       particle_structure * particle = particle_initialize (1024);
+
+       InitWindow (800, 600, "Xarticle");
+
+       Camera camera = { 0 };
+       camera.position = (Vector3){ 0.0f, 2.0f, 4.0f };    // Camera position
+       camera.target = (Vector3){ 0.0f, 2.0f, 0.0f };      // Camera looking at point
+       camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };          // Camera up vector (rotation towards target)
+       camera.fovy = 60.0f;                                // Camera field-of-view Y
+       camera.projection = CAMERA_PERSPECTIVE;             // Camera projection type
+
+       SetTargetFPS(60);
+
+       Texture texture = LoadTexture ("xui/fullscreen_on.png");
+
+       while (! WindowShouldClose ()) {
+               UpdateCamera(& camera, CAMERA_FIRST_PERSON);
+
+               BeginDrawing ();
+
+               ClearBackground(RAYWHITE);
+
+               BeginMode3D(camera);
+
+               DrawPlane((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector2){ 32.0f, 32.0f }, LIGHTGRAY); // Draw ground
+
+               if (IsKeyPressed (KEY_ONE)) {
+                       vector_3 p = {0,0,0};
+                       vector_3 t = {0,0,0};
+                       vector_3 s = {0.1f,0.1f,0.1f};
+
+                       particle_append (particle, 0, 1.0f, 0, 0, & p, & t, & s);
+               }
+
+               if (IsKeyPressed (KEY_TWO)) {
+                       vector_3 p = {1,1,1};
+
+                       particle_effect_splash (particle, 0, 2.0f, 0, 0, & p, 60, 0.03, 3);
+               }
+
+               if (IsKeyPressed (KEY_THREE)) {
+                       vector_3 p = {1,1,1};
+
+                       particle_effect_evaporate (particle, 0, 2.0f, 0, 0, & p, 20, 0.001, 3);
+               }
+
+               BeginBlendMode (BLEND_ALPHA_PREMULTIPLY);
+
+               for (uint i = 0; i < particle->count; ++i) {
+                       Vector3 vector = {particle->position [i]->x, particle->position [i]->y, particle->position [i]->z};
+                       DrawBillboard (camera, texture, vector, 1, RED);
+               }
+
+               EndBlendMode ();
+
+               EndMode3D();
+
+               DrawText (TextFormat ("count = %i", particle->count), 0, 0, 4, RED);
+
+               EndDrawing ();
+
+               particle_synchronize (particle, 60);
+       }
+
+       CloseWindow ();
+
+       particle = particle_deinitialize (particle);
+
+       return (0);
+}
diff --git a/xachine.h b/xachine.h
new file mode 100755 (executable)
index 0000000..aaed02a
--- /dev/null
+++ b/xachine.h
@@ -0,0 +1,456 @@
+///                 _     _
+/// __  ____ _  ___| |__ (_)_ __   ___
+/// \ \/ / _` |/ __| '_ \| | '_ \ / _ \
+///  >  < (_| | (__| | | | | | | |  __/
+/// /_/\_\__,_|\___|_| |_|_|_| |_|\___|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xachine - Minimalistic statical x86_64, 32-bit, ELF64, GEENOO/Leenoocks bytecode assembler following IA32e.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+#define elf_main_header_size (0x40)
+#define elf_text_sector_size (0x38)
+#define elf_data_sector_size (0x38)
+
+#define elf_header_size (elf_main_header_size + elf_text_sector_size + elf_data_sector_size)
+
+typedef enum {
+       operand_relative,               operand_register,               operand_memory,                 operand_immediate,
+       operand_count
+} operand_enumeration;
+
+typedef enum {
+       operation_memory,               operation_relative,             operation_number,               operation_string,
+       operation_add,                  operation_or,                   operation_add_carry,            operation_subtract_carry,
+       operation_and,                  operation_subtract,             operation_exclusive_or,         operation_compare,
+       operation_increment,            operation_decrement,            operation_not,                  operation_negate,
+       operation_unsigned_multiply,    operation_signed_multiply,      operation_unsigned_divide,      operation_signed_divide,
+       operation_rotate_left,          operation_rotate_right,         operation_rotate_left_carry,    operation_rotate_right_carry,
+       operation_shift_left_sign,      operation_shift_right,          operation_shift_left,           operation_shift_right_sign,
+       operation_jump_overflow,        operation_jump_not_overflow,    operation_jump_below,           operation_jump_above_equal,
+       operation_jump_equal,           operation_jump_not_equal,       operation_jump_below_equal,     operation_jump_above,
+       operation_jump_sign,            operation_jump_not_sign,        operation_jump_parity_even,     operation_jump_parity_odd,
+       operation_jump_lesser,          operation_jump_greater_equal,   operation_jump_lesser_equal,    operation_jump_greater,
+       operation_none,                 operation_return_near,          operation_system_call,          operation_call,
+       operation_jump,                 operation_move,
+       operation_count
+} operation_enumeration;
+
+#ifdef use_debug_printing
+
+static const char * operand_name [operand_count] = {
+       "rel",          "reg",          "mem",          "imm"
+};
+
+static const char * operation_name [operation_count] = {
+       "asmmem",       "asmrel",       "asmnum",       "asmstr",
+       "add",          "or",           "adc",          "sbb",          "and",          "sub",          "xor",          "cmp",
+       "inc",          "dec",          "not",          "neg",          "mul",          "imul",         "div",          "idiv",
+       "rol",          "ror",          "rcl",          "rcr",          "sal",          "shr",          "shl",          "sar",
+       "jo",           "jno",          "jb",           "jae",          "je",           "jne",          "jbe",          "ja",
+       "js",           "jns",          "jpe",          "jpo",          "jl",           "jge",          "jle",          "jg",
+       "nop",          "ret",          "syscall",      "call",         "jmp",          "mov"
+};
+
+#endif
+
+static uint    main_entry_point = 0;
+static uint    text_sector_size = 0;
+static uchar * text_sector_byte = null;
+static uint    data_sector_size = 0;    // This is unused, and it should be used...
+static uchar * data_sector_byte = null; // This is unused, and it should be used...
+
+static uint   empty_count = 1;
+static uint   empty_holes = 1;
+static uint * empty_array = null;
+static uint * empty_imbue = null;
+static uint * empty_store = null;
+
+static uchar elf_main_header_byte [elf_main_header_size] = { // These should be done properly...
+       0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x03,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
+       0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00,
+       0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static uchar elf_text_sector_byte [elf_text_sector_size] = {
+       0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static uchar elf_data_sector_byte [elf_data_sector_size] = {
+       0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static bool register_register  (uint to, uint from) { return ((to == operand_register) && (from == operand_register));  }
+static bool register_memory    (uint to, uint from) { return ((to == operand_register) && (from == operand_memory));    }
+static bool register_immediate (uint to, uint from) { return ((to == operand_register) && (from == operand_immediate)); }
+static bool memory_register    (uint to, uint from) { return ((to == operand_memory)   && (from == operand_register));  }
+static bool memory_immediate   (uint to, uint from) { return ((to == operand_memory)   && (from == operand_immediate)); }
+static bool register_relative  (uint to, uint from) { return ((to == operand_register) && (from == operand_relative));  }
+
+static uint absolute (void) { return (0x4010b0 - text_sector_size - 4); }
+static uint relative (void) { return (0x1000   - text_sector_size - 4); }
+
+static void replace (uchar * destination, uchar * source, ulong size) {
+       for (--size; size >= 0; --size) {
+               destination [size] = source [size];
+       }
+}
+
+static void inset (bool when, uchar data) {
+       text_sector_byte [text_sector_size] = data;
+
+       text_sector_size += (uint) when;
+}
+
+static void inset_immediate (bool when, uint data) {
+       inset (when, (data >>  0) & 0xff);
+       inset (when, (data >>  8) & 0xff);
+       inset (when, (data >> 16) & 0xff);
+       inset (when, (data >> 24) & 0xff);
+}
+
+static void inset_memory (bool when, uint data, uint base) {
+       empty_array [empty_holes] = text_sector_size;
+       empty_imbue [empty_holes] = data;
+
+       empty_holes += when;
+
+       inset_immediate (when, base);
+}
+
+static void inset_relative (bool when, uint data, uint base) {
+       empty_array [empty_holes] = 0;
+       empty_imbue [empty_holes] = data;
+
+       empty_holes += when;
+
+       inset_immediate (when, base);
+}
+
+static uint mc0 (uint code, uint base) {
+       return (0xc0 + 0x01 * (code % 8) + 0x08 * (base % 8));
+}
+
+static uint m05 (uint code) {
+       return (0x05 + 0x08 * code);
+}
+
+static uint store_relative (const uint * array) {
+       const uint relative = array [1];
+#ifdef use_debug_printing
+       print ("/3asmrel/- %i", relative);
+#endif
+       empty_array [empty_holes] = text_sector_size;
+       empty_imbue [empty_holes] = relative;
+
+       ++empty_holes;
+
+       return 1;
+}
+
+static uint store_memory (const uint * array) {
+       const uint memory = array [1];
+#ifdef use_debug_printing
+       print ("/3asmmem/- %i", memory);
+#endif
+       empty_store [memory] = text_sector_size;
+
+       ++empty_count;
+
+       return 1;
+}
+
+static uint store_number (const uint * array) {
+       const uint amount = array [1];
+
+#ifdef use_debug_printing
+       print ("/3asmnum/- %i", amount);
+#endif
+       for (uint index = 0; index < amount; ++index) {
+               inset_immediate (true, array [2 + index]);
+       }
+
+       return amount + 1;
+}
+
+static uint store_string (const uint * array) {
+       const uint amount = array [1];
+
+#ifdef use_debug_printing
+       print ("/3asmstr/- %i", amount);
+#endif
+       for (uint index = 0; index < amount; ++index) {
+               inset (true, array [2 + index]);
+       }
+
+       return amount + 1;
+}
+
+static uint build_double (const uint * array) {
+       const uint operation   = array [0];
+       const uint to          = array [1];
+       const uint destination = array [2];
+       const uint from        = array [3];
+       const uint source      = array [4];
+#ifdef use_debug_printing
+       print ("/3%s/- /6%s/- %i /6%s/- %i", operation_name [operation], operand_name [to], destination, operand_name [from], source);
+#endif
+       inset (register_immediate (to, from), 0x81);
+
+       // Seriously, what the fuck...?
+       inset (true, 0x01 + 0x08 * (operation - operation_add) +
+               destination * (register_immediate (to, from)) +
+               0x01 * register_immediate (to, from) +
+               0x02 * register_memory (to, from) +
+               0x04 * memory_immediate (to, from) +
+               0xc0 * register_immediate (to, from));
+
+       inset (register_register (to, from), mc0 (destination, source));
+
+       inset (register_memory (to, from), m05 (destination));
+       inset (memory_register (to, from), m05 (source));
+
+       inset_memory (register_memory (to, from), source, relative ());
+
+       inset_immediate (register_immediate (to, from), source);
+
+       inset_memory (memory_register (to, from), destination, relative ());
+       inset_memory (memory_immediate (to, from), destination, relative ());
+
+       inset_immediate (memory_immediate (to, from), source);
+
+       inset_memory (register_relative (to, from), source, absolute ());
+
+       return 4;
+}
+
+static uint build_single (const uint * array) {
+       const uint operation   = array [0];
+       const uint to          = array [1];
+       const uint destination = array [2];
+#ifdef use_debug_printing
+       print ("/3%s/- /6%s/- %i", operation_name [operation], operand_name [to], destination);
+#endif
+       inset (true,      0xf7 + 0x08 * ((operation == operation_increment) || (operation == operation_decrement)));
+       inset (to == operand_register, 0xc0 + 0x08 * (operation - operation_increment) + 0x01 * destination);
+       inset (to == operand_memory, 0x05 + 0x08 * (operation - operation_increment));
+
+       inset_memory (to == operand_memory, destination, relative ());
+
+       return 2;
+}
+
+static uint build_shift (const uint * array) {
+       const uint operation   = array [0];
+       const uint to          = array [1];
+       const uint destination = array [2];
+       const uint offset      = array [3];
+#ifdef use_debug_printing
+       print ("/3%s/- /6%s/- %i /cimm/- %i", operation_name [operation], operand_name [to], destination, offset);
+#endif
+       inset (true, 0xc1);
+
+       inset (to == operand_register, 0x05 + 0x08 * (operation - operation_rotate_left));
+       inset (to == operand_memory, 0xc0 + 0x08 * (operation - operation_rotate_left));
+
+       inset_memory (to == operand_memory, destination, relative ());
+
+       inset (true, offset);
+
+       return 3;
+}
+
+static uint build_static_1 (const uint * array) {
+       const uint operation = array [0];
+#ifdef use_debug_printing
+       print ("/3%s/-", operation_name [operation]);
+#endif
+       switch (operation) {
+               case operation_none: inset (true, 0x90);                     break;
+               case operation_return_near: inset (true, 0xc3);                     break;
+               case operation_system_call: inset (true, 0x0f); inset (true, 0x05); break;
+               default:                                          break;
+       }
+
+       return 0;
+}
+
+static uint build_jump_if (const uint * array) {
+       const uint operation = array [0];
+       const uint location  = array [1];
+#ifdef use_debug_printing
+       print ("/3%s/- %i", operation_name [operation], location);
+#endif
+       inset (true, 0x0f);
+       inset (true, 0x80 + operation - operation_jump_overflow);
+
+       inset_memory (true, location, -text_sector_size - 4);
+
+       return 2;
+}
+
+static uint build_jump (const uint * array) {
+       const uint to          = array [1];
+       const uint destination = array [2];
+#ifdef use_debug_printing
+       print ("/3jmp/- /6%s/- %i", operand_name [to], destination);
+#endif
+       inset (to == operand_register, 0xff);
+       inset (to == operand_register, 0xe0 + 0x01 * destination);
+       inset (to == operand_relative, 0xe9);
+
+       inset_memory (to == operand_relative, destination, -text_sector_size - 4);
+
+       return 2;
+}
+
+static uint build_move (const uint * array) {
+       const uint to          = array [1];
+       const uint destination = array [2];
+       const uint from        = array [3];
+       const uint source      = array [4];
+#ifdef use_debug_printing
+       print ("/3mov/- /6%s/- %i /6%s/- %i", operand_name [to], destination, operand_name [from], source);
+#endif
+       inset (register_register (to, from), 0x89);
+       inset (memory_register   (to, from), 0x8b);
+       inset (register_memory   (to, from), 0x89);
+       inset (memory_register   (to, from), m05 (destination));
+       inset (register_memory   (to, from), m05 (source));
+
+       inset (register_register (to, from), mc0 (destination, source));
+
+       inset ((to == operand_register) && ((from == operand_immediate) || (from == operand_relative)), 0xb8 + 0x01 * destination);
+
+       inset (memory_immediate (to, from), 0xc7);
+
+       inset_memory (register_memory   (to, from), source,      relative ());
+       inset_memory (memory_register   (to, from), destination, relative ());
+       inset_memory (memory_immediate  (to, from), destination, relative ());
+       inset_memory (register_relative (to, from), source,      0x4010b0);
+
+       inset_immediate (register_immediate (to, from), source);
+       inset_immediate (memory_immediate   (to, from), source);
+
+       return 4;
+}
+
+static uint build_call (const uint * array) {
+       const uint from   = array [1];
+       const uint source = array [2];
+#ifdef use_debug_printing
+       print ("/3call/- /6%s/- %i", operand_name [from], source);
+#endif
+       inset (from == operand_relative, 0xe8);
+       inset (from == operand_register, 0xff);
+       inset (from == operand_register, 0xd0 + 0x01 * source);
+
+       inset_memory (from == operand_relative, source, -text_sector_size - 4);
+
+       return 2;
+}
+
+static uint (* build_instruction [operation_count]) (const uint * array) = {
+       store_memory,   // operation_memory : LABEL
+       store_relative, // operation_relative : "IMPLEMENTED"
+       store_number,
+       store_string,
+       build_double,   build_double,   build_double,   build_double,   build_double,   build_double,   build_double,   build_double,
+       build_single,   build_single,   build_single,   build_single,   build_single,   build_single,   build_single,   build_single,
+       build_shift,    build_shift,    build_shift,    build_shift,    build_shift,    build_shift,    build_shift,    build_shift,
+       build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,
+       build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,
+       build_static_1, build_static_1, build_static_1, build_call,     build_jump,     build_move
+};
+
+static void assemble (uint count, const uint * array, uint external_memory, uint internal_memory) {
+       text_sector_byte = arena_add (external_memory * sizeof (* text_sector_byte));
+       data_sector_byte = arena_add (external_memory * sizeof (* text_sector_byte));
+
+       empty_array = arena_add (internal_memory * sizeof (* empty_array));
+       empty_imbue = arena_add (internal_memory * sizeof (* empty_imbue));
+       empty_store = arena_add (internal_memory * sizeof (* empty_store));
+
+       for (uint index = 0; index < count; ++index) {
+               const uint size = text_sector_size;
+
+               uchar byte = 0;
+#ifdef use_debug_nopping
+               inset (array [index] > operation_string, 0x90);
+#endif
+               index += build_instruction [array [index]] (& array [index]);
+#ifdef use_debug_printing
+               print (" /0--/- ");
+               for (byte = size; byte < text_sector_size; ++byte) {
+                       print ("/5%s/- ", format_to_string ((uchar) text_sector_byte [byte], false, 16, 2, '0'));
+               }
+               print ("\n");
+#endif
+       }
+
+       main_entry_point = empty_store [0];
+
+       for (uint index = 1; index < empty_holes; ++index) {
+               uint set = 0;
+               uint get = empty_array [index];
+
+               replace ((uchar *) & set, & text_sector_byte [get], sizeof (set));
+
+               set += empty_store [empty_imbue [index]];
+
+               replace (& text_sector_byte [get], (uchar *) & set, sizeof (get));
+       }
+}
+
+static void elf_main_header (uint entry_point, bool has_program, bool for_linux, bool for_x86_64) {
+       uint enter = entry_point + 0x4000b0;
+
+       elf_main_header_byte [16] = (has_program) ? 0x02 : 0x03;
+       elf_main_header_byte [ 7] = (for_linux)   ? 0x03 : 0x00;
+       elf_main_header_byte [18] = (for_x86_64)  ? 0x3e : 0x00;
+
+       memory_copy (& elf_main_header_byte [24], & enter, sizeof (enter));
+}
+
+static void elf_text_sector (uint text_size, uint data_size) {
+       uint text = elf_header_size + text_size - data_size;
+
+       memory_copy (& elf_text_sector_byte [32], & text, sizeof (text));
+       memory_copy (& elf_text_sector_byte [40], & text, sizeof (text));
+}
+
+static void elf_data_sector (uint text_size, uint data_size) {
+       uint data = data_size;
+       uint core = elf_header_size + text_size - data_size;
+       uint move = 0x401000 + core;
+
+       memory_copy (& elf_data_sector_byte [ 8], & core, sizeof (core));
+       memory_copy (& elf_data_sector_byte [16], & move, sizeof (move));
+       memory_copy (& elf_data_sector_byte [24], & move, sizeof (move));
+       memory_copy (& elf_data_sector_byte [32], & data, sizeof (data));
+       memory_copy (& elf_data_sector_byte [40], & data, sizeof (data));
+}
diff --git a/xanguage.h b/xanguage.h
new file mode 100755 (executable)
index 0000000..3efd312
--- /dev/null
@@ -0,0 +1,201 @@
+/// __  ____ _ _ __   __ _ _   _  __ _  __ _  ___
+/// \ \/ / _` | '_ \ / _` | | | |/ _` |/ _` |/ _ \
+///  >  < (_| | | | | (_| | |_| | (_| | (_| |  __/
+/// /_/\_\__,_|_| |_|\__, |\__,_|\__,_|\__, |\___|
+///                  |___/             |___/
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xanguage - Syntax definitions of programming languages that I care about (and some that I don't care about).
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+typedef enum {
+       language_common,                language_ada,                   language_c,                     language_cpp,
+       language_d,                     language_eaxhla,                language_flat,                  language_fortran,
+       language_pascal,                language_python,                language_go,                    language_lua,
+       language_bash,                  language_haskell,               language_valgrind,
+       language_count
+} language_enumeration;
+
+typedef struct {
+       uint comment_colour;
+       uint processor_colour;
+       uint character_colour;
+       uint string_colour;
+       uint keyword_colour;
+       uint type_colour;
+       uint bracket_colour;
+       uint operator_colour;
+       uint number_colour;
+       uint lowercase_colour;
+       uint uppercase_colour;
+       uint underscore_colour;
+       uint register_colour;
+       uint extension_colour;
+       uint fatal_colour;
+       uint comment_effect;
+       uint processor_effect;
+       uint character_effect;
+       uint string_effect;
+       uint keyword_effect;
+       uint type_effect;
+       uint bracket_effect;
+       uint operator_effect;
+       uint number_effect;
+       uint lowercase_effect;
+       uint uppercase_effect;
+       uint underscore_effect;
+       uint register_effect;
+       uint extension_effect;
+       uint fatal_effect;
+} language_structure;
+
+#include <xolatile/xanguage/common.h>
+#include <xolatile/xanguage/ada.h>
+#include <xolatile/xanguage/c.h>
+#include <xolatile/xanguage/c++.h>
+#include <xolatile/xanguage/d.h>
+#include <xolatile/xanguage/eaxhla.h>
+#include <xolatile/xanguage/flat.h>
+#include <xolatile/xanguage/fortran.h>
+#include <xolatile/xanguage/pascal.h>
+#include <xolatile/xanguage/python.h>
+#include <xolatile/xanguage/go.h>
+#include <xolatile/xanguage/lua.h>
+#include <xolatile/xanguage/bash.h>
+#include <xolatile/xanguage/haskell.h>
+#include <xolatile/xanguage/valgrind.h>
+
+static language_structure * language_initialize (bool true_colour) {
+       language_structure * language = allocate (sizeof (* language));
+
+       if (true_colour == true) {
+               language->comment_colour    = 0xff777777u;
+               language->processor_colour  = 0xff3377aau;
+               language->character_colour  = 0xff7733ccu;
+               language->string_colour     = 0xffcc3377u;
+               language->keyword_colour    = 0xff33cceeu;
+               language->type_colour       = 0xff55cceeu;
+               language->bracket_colour    = 0xffee5533u;
+               language->operator_colour   = 0xffeeaa33u;
+               language->number_colour     = 0xffee33aau;
+               language->lowercase_colour  = 0xffccccccu;
+               language->uppercase_colour  = 0xffeeeeeeu;
+               language->underscore_colour = 0xffaaaaaau;
+               language->register_colour   = 0xff5577aau;
+               language->extension_colour  = 0xff55aaccu;
+               language->fatal_colour      = 0xffcc7755u;
+       } else {
+               language->comment_colour    = colour_grey;
+               language->processor_colour  = colour_cyan;
+               language->character_colour  = colour_pink;
+               language->string_colour     = colour_pink;
+               language->keyword_colour    = colour_yellow;
+               language->type_colour       = colour_yellow;
+               language->bracket_colour    = colour_blue;
+               language->operator_colour   = colour_cyan;
+               language->number_colour     = colour_pink;
+               language->lowercase_colour  = colour_white;
+               language->uppercase_colour  = colour_white;
+               language->underscore_colour = colour_white;
+               language->register_colour   = colour_cyan;
+               language->extension_colour  = colour_yellow;
+               language->fatal_colour      = colour_red;
+               language->comment_effect    = effect_bold;
+               language->processor_effect  = effect_italic;
+               language->character_effect  = effect_bold;
+               language->string_effect     = effect_normal;
+               language->keyword_effect    = effect_bold;
+               language->type_effect       = effect_normal;
+               language->bracket_effect    = effect_bold;
+               language->operator_effect   = effect_normal;
+               language->number_effect     = effect_bold;
+               language->lowercase_effect  = effect_normal;
+               language->uppercase_effect  = effect_bold;
+               language->underscore_effect = effect_italic;
+               language->register_effect   = effect_italic;
+               language->extension_effect  = effect_italic;
+               language->fatal_effect      = effect_bold;
+       }
+
+       return (language);
+}
+
+static language_structure * language_deinitialize (language_structure * language) {
+       return (deallocate (language));
+}
+
+static void (* language_highlighter (language_enumeration language)) (language_structure * language, syntax_structure * syntax) {
+       static const void (* highlighter [language_count]) (language_structure * language, syntax_structure * syntax) = {
+               language_highlight_common,      language_highlight_ada,         language_highlight_c,           language_highlight_cpp,
+               language_highlight_d,           language_highlight_eaxhla,      language_highlight_flat,        language_highlight_fortran,
+               language_highlight_pascal,      language_highlight_python,      language_highlight_go,          language_highlight_lua,
+               language_highlight_bash,        language_highlight_haskell,     language_highlight_valgrind
+       };
+
+       fatal_failure (language >= language_count, "language_highlighter: Language index not in enumeration.");
+
+       return (highlighter [language]);
+}
+
+static char * language_short_option (language_enumeration language) {
+       static const char * short_option [language_count] = {
+               "-X",   "-A",   "-C",   "-S",   "-D",   "-E",   "-T",   "-F",   "-P",   "-Y",   "-G",   "-L",   "-B",   "-H",   "-V"
+       };
+
+       fatal_failure (language >= language_count, "language_short_option: Language index not in enumeration.");
+
+       return (short_option [language]);
+}
+
+static char * language_long_option (language_enumeration language) {
+       static const char * long_option [language_count] = {
+               "--common",     "--ada",        "--c",          "--cpp",        "--d",          "--eaxhla",     "--flat",       "--fortran",
+               "--pascal",     "--python",     "--go",         "--lua",        "--bash",       "--haskell",    "--valgrind"
+       };
+
+       fatal_failure (language >= language_count, "language_long_option: Language index not in enumeration.");
+
+       return (long_option [language]);
+}
+
+static char * language_identifier (language_enumeration language) {
+       static const char * identifier [language_count] = {
+               "Common",       "Ada",          "C",            "C++",          "D",            "EAXHLA",       "Flat",         "Fortran",
+               "Pascal",       "Python",       "Go",           "Lua",          "Bash",         "Haskell",      "Valgrind"
+       };
+
+       fatal_failure (language >= language_count, "language_identifier: Language index not in enumeration.");
+
+       return (identifier [language]);
+}
+
+static void language_conditionally_select (language_structure * language, syntax_structure * syntax, uint select) {
+       if (syntax->count == 0) {
+               if ((select == file_type_c_source) || (select == file_type_c_header)) {
+                       language_highlight_c (language, syntax);
+               } else if ((select == file_type_ada_sexy_body) || (select == file_type_ada_specification)) {
+                       language_highlight_ada (language, syntax);
+               } else if ((select == file_type_cpp_source) || (select == file_type_cpp_header)) {
+                       language_highlight_cpp (language, syntax);
+               } else if (select == file_type_flat_assembly) {
+                       language_highlight_flat (language, syntax);
+               } else if (select == file_type_fortran_90_source) {
+                       language_highlight_fortran (language, syntax);
+               } else if (select == file_type_pascal_source) {
+                       language_highlight_pascal (language, syntax);
+               } else if (select == file_type_eax_assembly) {
+                       language_highlight_eaxhla (language, syntax);
+               } else if (select == file_type_python_script) {
+                       language_highlight_python (language, syntax);
+               } else {
+                       language_highlight_common (language, syntax);
+               }
+       }
+}
diff --git a/xanguage/ada.h b/xanguage/ada.h
new file mode 100755 (executable)
index 0000000..0e453b1
--- /dev/null
@@ -0,0 +1,31 @@
+static void language_highlight_ada (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/&|()\" \t\r\n";
+
+       const char * keywords [] = {
+               "abort",        "else",         "new",          "return",       "abs",          "elsif",        "not",          "reverse",
+               "abstract",     "end",          "null",         "accept",       "entry",        "select",       "access",       "of",
+               "separate",     "aliased",      "exit",         "or",           "some",         "all",          "others",       "subtype",
+               "and",          "for",          "out",          "array",        "function",     "at",           "tagged",       "generic",
+               "package",      "task",         "begin",        "goto",         "pragma",       "body",         "private",      "then",
+               "type",         "case",         "in",           "constant",     "until",        "is",           "raise",        "use",
+               "if",           "declare",      "range",        "delay",        "limited",      "record",       "when",         "delta",
+               "loop",         "rem",          "while",        "digits",       "renames",      "with",         "do",           "mod",
+               "requeue",      "xor",          "procedure",    "protected",    "interface",    "synchronized", "exception",    "overriding",
+               "terminate"
+       };
+
+       syntax_define (syntax, false, false, "--", "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "'",  "'",  '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"", "\"", '\\', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       syntax_define (syntax, true, false, "()",             "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+-*/&|'", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,    language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour, language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour, language->uppercase_effect);
+}
diff --git a/xanguage/bash.h b/xanguage/bash.h
new file mode 100755 (executable)
index 0000000..351c2f3
--- /dev/null
@@ -0,0 +1,24 @@
+static void language_highlight_bash (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/%!&~^?|@#$()[]{}'\" \t\r\n";
+
+       const char * keywords [] = {
+               "exit",         "set",          "elif",         "done",         "in",           "then",         "function",     "fi",
+               "if",           "else",         "do",           "while",        "for"
+       };
+
+       syntax_define (syntax, false, false, "#",   "\n", '\0', language->comment_colour, language->comment_effect);
+       syntax_define (syntax, false, false, "'",   "'",  '\0', language->string_colour,  language->string_effect);
+       syntax_define (syntax, false, false, "\"",  "\"", '\0', language->string_colour,  language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]{}",                "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+*-/%!&~^?|@#$", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/c++.h b/xanguage/c++.h
new file mode 100755 (executable)
index 0000000..131176d
--- /dev/null
@@ -0,0 +1,53 @@
+static void language_highlight_cpp (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/%!&~^?|()[]{}'\" \t\r\n";
+
+       const char * keywords [] = {
+               "alignas",      "alignof",      "and",          "asm",          "auto",         "break",        "case",
+               "catch",        "class",        "compl",        "concept",      "const",        "consteval",    "constexpr",
+               "constinit",    "continue",     "decltype",     "default",      "delete",       "do",           "else",
+               "enum",         "explicit",     "export",       "extern",       "false",        "for",          "friend",
+               "goto",         "if",           "inline",       "mutable",      "namespace",    "new",
+               "noexcept",     "not",          "nullptr",      "operator",     "or",           "private",      "protected",    "public",
+               "reflexpr",     "register",     "requires",     "return",       "sizeof",       "static",
+               "struct",       "switch",       "synchronized", "template",     "this",         "throw",        "true",         "try",
+               "typedef",      "typeid",       "typename",     "union",        "using",        "virtual",
+               "volatile",     "while",        "xor",          "final",        "override",     "import",       "module"
+       };
+
+       const char * types [] = {
+               "void",         "bool",         "off_t",        "va_list",      "float",        "double",       "float_t",      "double_t",
+               "char",         "short",        "int",          "long",         "uchar",        "ushort",       "uint",         "ulong",
+               "int8_t",       "int16_t",      "int32_t",      "int64_t",      "uint8_t",      "uint16_t",     "uint32_t",     "uint64_t",
+               "signed",       "unsigned",     "size_t",       "ssize_t"
+       };
+
+       const char * commons [] = {
+               "std",          "FILE",         "DIR",          "EOF",          "va_arg",       "va_start",     "va_end",       "va_copy"
+       };
+
+       syntax_define (syntax, false, false, "/*", "*/", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "//", "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "#",  "\n", '\\', language->processor_colour, language->processor_effect);
+       syntax_define (syntax, false, false, "'",  "'",  '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"", "\"", '\\', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       for (ulong word = 0; word < array_length (types); ++word) {
+               syntax_define (syntax, false, true, types [word], separators, '\0', language->type_colour, language->type_effect);
+       }
+
+       for (ulong word = 0; word < array_length (commons); ++word) {
+               syntax_define (syntax, false, true, commons [word], separators, '\0', language->extension_colour, language->extension_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]{}",             "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+*-/%!&~^?|", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/c.h b/xanguage/c.h
new file mode 100755 (executable)
index 0000000..8005724
--- /dev/null
@@ -0,0 +1,49 @@
+static void language_highlight_c (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/%!&~^?|()[]{}'\" \t\r\n";
+
+       const char * keywords [] = {
+               "register",     "volatile",     "auto",         "const",        "static",       "extern",       "if",           "else",
+               "do",           "while",        "for",          "continue",     "switch",       "case",         "default",      "break",
+               "enum",         "union",        "struct",       "typedef",      "goto",         "return",       "sizeof",       "inline",
+               "restrict",     "true",         "false"
+       };
+
+       const char * types [] = {
+               "void",         "bool",         "off_t",        "va_list",      "float",        "double",       "float_t",      "double_t",
+               "char",         "short",        "int",          "long",         "uchar",        "ushort",       "uint",         "ulong",
+               "int8_t",       "int16_t",      "int32_t",      "int64_t",      "uint8_t",      "uint16_t",     "uint32_t",     "uint64_t",
+               "signed",       "unsigned",     "size_t",       "ssize_t"
+       };
+
+       const char * commons [] = {
+               "null",         "NULL",         "FILE",         "DIR",          "va_arg",       "va_start",     "va_end",       "va_copy",
+               "alignas",      "alignof",      "offsetof",     "typeof",       "EOF",          "ABS",          "MIN",          "MAX",
+               "ARRAYSIZE",    "SWAP",         "UNUSED",       "UNREACHABLE",  "STRINGIFY",    "CONCAT",       "assert",       "static_assert"
+       };
+
+       syntax_define (syntax, false, false, "/*",  "*/", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "//",  "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "#",   "\n", '\\', language->processor_colour, language->processor_effect);
+       syntax_define (syntax, false, false, "'",   "'",  '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"",  "\"", '\\', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       for (ulong word = 0; word < array_length (types); ++word) {
+               syntax_define (syntax, false, true, types [word], separators, '\0', language->type_colour, language->type_effect);
+       }
+
+       for (ulong word = 0; word < array_length (commons); ++word) {
+               syntax_define (syntax, false, true, commons [word], separators, '\0', language->extension_colour, language->extension_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]{}",             "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+*-/%!&~^?|", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/common.h b/xanguage/common.h
new file mode 100755 (executable)
index 0000000..652b10b
--- /dev/null
@@ -0,0 +1,9 @@
+static void language_highlight_common (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+*-/%!&~^?|()[]{}'\"@#$` \t\r\n";
+
+       syntax_define (syntax, false, false, "'",                      "'",        '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"",                     "\"",       '\\', language->string_colour,    language->string_effect);
+       syntax_define (syntax, true,  false, "()[]{}",                 "",         '\0', language->bracket_colour,   language->bracket_effect);
+       syntax_define (syntax, true,  false, ".,:;<=>+*-/%!&~^?|@#$`", "",         '\0', language->operator_colour,  language->operator_effect);
+       syntax_define (syntax, true,  true,  "0123456789",             separators, '\0', language->number_colour,    language->number_effect);
+}
diff --git a/xanguage/d.h b/xanguage/d.h
new file mode 100755 (executable)
index 0000000..d5a043a
--- /dev/null
@@ -0,0 +1,49 @@
+static void language_highlight_d (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/%!&~^?|@()[]{}'\"` \t\r\n";
+
+       const char * keywords [] = {
+               "abstract",     "alias",        "align",        "asm",          "assert",       "auto",         "body",         "bool",
+               "break",        "byte",         "case",         "cast",         "catch",        "cdouble",      "cent",         "cfloat",
+               "char",         "class",        "const",        "continue",     "creal",        "dchar",        "debug",        "default",
+               "delegate",     "delete",       "deprecated",   "do",           "double",       "else",         "enum",         "export",
+               "extern",       "false",        "final",        "finally",      "float",        "for",          "foreach",      "with",
+               "function",     "goto",         "idouble",      "if",           "ifloat",       "immutable",    "import",       "in",
+               "inout",        "int",          "interface",    "invariant",    "ireal",        "is",           "lazy",         "long",
+               "macro",        "mixin",        "module",       "new",          "nothrow",      "null",         "out",          "override",
+               "package",      "pragma",       "private",      "protected",    "public",       "pure",         "real",         "ref",
+               "return",       "scope",        "shared",       "short",        "static",       "struct",       "super",        "switch",
+               "synchronized", "template",     "this",         "throw",        "true",         "try",          "typeid",       "typeof",
+               "ubyte",        "ucent",        "uint",         "ulong",        "union",        "unittest",     "ushort",       "version",
+               "void",         "wchar",        "while",        "foreach_reverse"
+       };
+
+       const char * types [] = {
+               "byte",         "ubyte",        "short",        "ushort",       "int",          "uint",         "long",         "ulong",
+               "cent",         "ucent",        "char",         "wchar",        "dchar",        "float",        "double",       "real",
+               "ifloat",       "idouble",      "ireal",        "cfloat",       "cdouble",      "creal",        "void",         "bool",
+               "string"
+       };
+
+       syntax_define (syntax, false, false, "/+",  "+/", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "/*",  "*/", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "//",  "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "'",   "'",  '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"",  "\"", '\\', language->string_colour,    language->string_effect);
+       syntax_define (syntax, false, false, "`",   "`",  '\0', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       for (ulong word = 0; word < array_length (types); ++word) {
+               syntax_define (syntax, false, true, types [word], separators, '\0', language->type_colour, language->type_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]{}",              "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+*-/%!&~^?|@", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/eaxhla.h b/xanguage/eaxhla.h
new file mode 100755 (executable)
index 0000000..ca99f20
--- /dev/null
@@ -0,0 +1,79 @@
+static void language_highlight_eaxhla (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,+-*/[]<>=; \t\r\n";
+
+       const char * declarations [] = {
+               "program",      "procedure",    "machine",      "library",      "fast",         "unix",         "begin",        "end",
+               "if",           "then",         "else",         "repeat",       "break",        "continue",     "until",        "exit",
+               "fastcall",     "shell",        "alias",        "macro",        "scope",        "unscope",      "use",          "include"
+       };
+
+       const char * types [] = {
+               "s8",           "s16",          "s32",          "s64",          "u8",           "u16",          "u32",          "u64",
+               "f32",          "f64",          "f80",          "v0",           "s128",         "u128",         "s256",         "u256",
+               "s512",         "u512"
+       };
+
+       const char * instructions [] = {
+               "jnpe",         "jpo",          "jnpo",         "jpe",          "jnb",           "jae",          "jnbe",          "ja",
+               "jna",          "jbe",          "jnae",         "jb",           "jnl",           "jge",          "jnle",          "jg",
+               "jng",          "jle",          "jnge",         "jl",           "cmovng",        "cmovle",       "cmovnge",       "cmovl",
+               "cmovnpe",      "cmovpo",       "cmovnpo",      "cmovpe",       "cmovnb",        "cmovae",       "cmovnbe",       "cmova",
+               "cmovna",       "cmovbe",       "cmovnae",      "cmovb",        "cmovnl",        "cmovge",       "cmovnle",       "cmovg",
+               "setnpe",       "setpo",        "setnpo",       "setpe",        "setnb",         "setae",        "setnbe",        "seta",
+               "setna",        "setbe",        "setnae",       "setb",         "setnl",         "setge",        "setnle",        "setg",
+               "setng",        "setle",        "setnge",       "setl",         "enter",         "call",         "jmp",           "mov",
+               "add",          "or",           "adc",          "sbb",          "and",           "sub",          "xor",           "cmp",
+               "inc",          "dec",          "not",          "neg",          "mul",           "imul",         "div",           "idiv",
+               "fadd",         "fmul",         "fcom",         "fcomp",        "fsub",          "fsubr",        "fdiv",          "fdivr",
+               "rol",          "ror",          "rcl",          "rcr",          "sal",           "shr",          "shl",           "sar",
+               "nop",          "retn",         "retf",         "leave",        "popf",          "pushf",        "in",            "out",
+               "syscall",      "cpuid",        "fnop",         "fchs",         "fabs",          "ftst",         "fxam",          "fld1",
+               "fldl2t",       "fldl2e",       "fldpi",        "fldlg2",       "fldln2",        "fldz",         "f2xm1",         "fyl2x",
+               "fptan",        "fpatan",       "fxtract",      "fprem1",       "fdecstp",       "fincstp",      "fprem",         "fyl2xp1",
+               "fsqrt",        "fsincos",      "frndint",      "fscale",       "fsin",          "fcos",         "pop",           "push",
+               "bswap",        "bsf",          "bsr",          "loop",         "loope",         "loopne"
+       };
+
+       const char * registers [] = {
+               "rax",          "rcx",          "rdx",          "rbx",          "rsp",          "rbp",          "rsi",          "rdi",
+               "r8",           "r9",           "r10",          "r11",          "r12",          "r13",          "r14",          "r15",
+               "eax",          "ecx",          "edx",          "ebx",          "esp",          "ebp",          "esi",          "edi",
+               "r8d",          "r9d",          "r10d",         "r11d",         "r12d",         "r13d",         "r14d",         "r15d",
+               "ax",           "cx",           "dx",           "bx",           "sp",           "bp",           "si",           "di",
+               "r8w",          "r9w",          "r10w",         "r11w",         "r12w",         "r13w",         "r14w",         "r15w",
+               "al",           "cl",           "dl",           "bl",           "spl",          "bpl",          "sil",          "dil",
+               "r8b",          "r9b",          "r10b",         "r11b",         "r12b",         "r13b",         "r14b",         "r15b"
+       };
+
+       int word;
+
+       syntax_define (syntax, false, false, "#",   "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "---", "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "//",  "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "'",   "'",  '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"",  "\"", '\\', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (declarations); ++word) {
+               syntax_define (syntax, false, true, declarations [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       for (ulong word = 0; word < array_length (types); ++word) {
+               syntax_define (syntax, false, true, types [word], separators, '\0', language->type_colour, language->type_effect);
+       }
+
+       for (ulong word = 0; word < array_length (instructions); ++word) {
+               syntax_define (syntax, false, true, instructions [word], separators, '\0', language->extension_colour, language->extension_effect);
+       }
+
+       for (ulong word = 0; word < array_length (registers); ++word) {
+               syntax_define (syntax, false, true, registers [word], separators, '\0', language->register_colour, language->register_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]{}",       "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,+*-/%$<>=;", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/flat.h b/xanguage/flat.h
new file mode 100755 (executable)
index 0000000..eabf301
--- /dev/null
@@ -0,0 +1,66 @@
+static void language_highlight_flat (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,+-=:;(){}[]%$<> \t\r\n";
+
+       const char * declarations [] = {
+               "format",       "executable",   "readable",     "writable",     "segment",      "sector",       "entry",        "macro",
+               "db",           "dw",           "dd",           "dq",           "rb",           "rw",           "rd",           "rq"
+       };
+
+       const char * instructions [] = {
+               "mov",          "movabs",       "movapd",       "movaps",       "movebe",       "movsd",        "movsx",        "movzx",
+               "movsxd",       "movd",         "movq",         "movs",         "movsb",        "movsw",        "movsd",        "movsq",
+               "cmovmp",       "cmovrcxz",     "cmovc",        "cmovnc",       "cmove",        "cmovne",       "cmovz",        "cmovnz",
+               "cmovg",        "cmovng",       "cmovge",       "cmovnge",      "cmovl",        "cmovnl",       "cmovle",       "cmovnle",
+               "cmova",        "cmovna",       "cmovae",       "cmovnae",      "cmovb",        "cmovnb",       "cmovbe",       "cmovnbe",
+               "cmovs",        "cmovns",       "cmovo",        "cmovno",       "cmovp",        "cmovnp",       "cmovpo",       "cmovpe",
+               "cmp",          "cmps",         "cmpsb",        "cmpsw",        "cmpsd",        "cmpsq",        "cmpxchg",      "lea",
+               "monitor",      "cpuid",        "in",           "out",          "syscall",      "sysenter",     "sysret",       "sysexit",
+               "swap",         "bswap",        "pop",          "push",         "call",         "ret",          "enter",        "leave",
+               "and",          "or",           "not",          "neg",          "sal",          "sar",          "shl",          "shr",
+               "inc",          "dec",          "add",          "sub",          "mul",          "div",          "imul",         "idiv",
+               "nop",          "fnop",         "adc",          "sbb",          "aaa",          "aas",          "aam",          "aad",
+               "jmp",          "jrcxz",        "jc",           "jnc",          "je",           "jne",          "jz",           "jnz",
+               "jg",           "jng",          "jge",          "jnge",         "jl",           "jnl",          "jle",          "jnle",
+               "ja",           "jna",          "jae",          "jnae",         "jb",           "jnb",          "jbe",          "jnbe",
+               "js",           "jns",          "jo",           "jno",          "jp",           "jnp",          "jpo",          "jpe",
+               "rep",          "repe",         "repz",         "repne",        "repnz",        "loop",         "loope",        "loopne"
+       };
+
+       const char * registers [] = {
+               "rax",          "rcx",          "rdx",          "rbx",          "rsp",          "rbp",          "rsi",          "rdi",
+               "r8",           "r9",           "r10",          "r11",          "r12",          "r13",          "r14",          "r15",
+               "eax",          "ecx",          "edx",          "ebx",          "esp",          "ebp",          "esi",          "edi",
+               "r8d",          "r9d",          "r10d",         "r11d",         "r12d",         "r13d",         "r14d",         "r15d",
+               "ax",           "cx",           "dx",           "bx",           "sp",           "bp",           "si",           "di",
+               "r8w",          "r9w",          "r10w",         "r11w",         "r12w",         "r13w",         "r14w",         "r15w",
+               "al",           "cl",           "dl",           "bl",           "spl",          "bpl",          "sil",          "dil",
+               "r8b",          "r9b",          "r10b",         "r11b",         "r12b",         "r13b",         "r14b",         "r15b",
+               "ah",           "ch",           "dh",           "bh"
+       };
+
+       int word;
+
+       syntax_define (syntax, false, false, ";",  "\n", '\0', language->comment_colour, language->comment_effect);
+       syntax_define (syntax, false, false, "'",  "'",  '\\', language->string_colour,  language->string_effect);
+       syntax_define (syntax, false, false, "\"", "\"", '\\', language->string_colour,  language->string_effect);
+
+       for (ulong word = 0; word < array_length (declarations); ++word) {
+               syntax_define (syntax, false, true, declarations [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       for (ulong word = 0; word < array_length (instructions); ++word) {
+               syntax_define (syntax, false, true, instructions [word], separators, '\0', language->extension_colour, language->extension_effect);
+       }
+
+       for (ulong word = 0; word < array_length (registers); ++word) {
+               syntax_define (syntax, false, true, registers [word], separators, '\0', language->register_colour, language->register_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]{}",      "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,+-=:;%$<>", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/fortran.h b/xanguage/fortran.h
new file mode 100755 (executable)
index 0000000..e24923a
--- /dev/null
@@ -0,0 +1,47 @@
+static void language_highlight_fortran (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ",:<=>+-*/&()[]\"\' \t\r\n";
+
+       const char * keywords [] = {
+               "allocatable",  "allocate",     "associate",    "backspace",    "block",        "call",         "case",         "common",
+               "contains",     "cycle",        "data",         "deallocate",   "d0",           "do",           "else",         "elseif",
+               "end",          "enddo",        "endfile",      "endif",        "entry",        "equivalence",  "exit",         "external",
+               "forall",       "format",       "function",     "goto",         "if",           "implicit",     "inquire",      "intent",
+               "intrinsic",    "module",       "namelist",     "none",         "nullify",      "only",         "open",         "optional",
+               "parameter",    "pointer",      "print",        "private",      "program",      "public",       "read",         "recursive",
+               "return",       "rewind",       "save",         "select",       "sequence",     "stop",         "subroutine",   "target",
+               "then",         "to",           "type",         "use",          "where",        "write"
+       };
+
+       const char * types [] = {
+               "character",    "integer",      "logical",      "real",         "complex"
+       };
+
+       const char * subkeywords [] = {
+               ".and.",        ".or.",         ".not.",        ".true.",       ".false.",      "in",           "out",          "len",
+               "dimension",    "modulo",       "advance"
+       };
+
+       syntax_define (syntax, false, false, "!",  "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "'",  "'",  '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"", "\"", '\\', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       for (ulong word = 0; word < array_length (subkeywords); ++word) {
+               syntax_define (syntax, false, true, subkeywords [word], separators, '\0', language->processor_colour, language->processor_effect);
+       }
+
+       for (ulong word = 0; word < array_length (types); ++word) {
+               syntax_define (syntax, false, true, types [word], separators, '\0', language->type_colour, language->type_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]",       "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ",:<=>+-*/&", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/go.h b/xanguage/go.h
new file mode 100755 (executable)
index 0000000..38919e8
--- /dev/null
@@ -0,0 +1,46 @@
+static void language_highlight_go (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/%!&~^?|()[]{}'\"` \t\r\n";
+
+       const char * keywords [] = {
+               "break",        "default",      "func",         "interface",    "select",       "case",         "defer",        "go",
+               "struct",       "else",         "goto",         "package",      "switch",       "const",        "var",          "for",
+               "fallthrough",  "if",           "range",        "type",         "continue",     "import",       "return"
+       };
+
+       const char * types [] = {
+               "map",          "uint",         "int",          "uintptr",      "uint8",        "uint16",       "uint32",       "uint64",
+               "int8",         "int16",        "int32",        "int64",        "float32",      "float64",      "complex64",    "complex128",
+               "byte",         "rune",         "string",       "chan",         "bool"
+
+       };
+
+       const char * commons [] = {
+               "true",         "false",        "nil",          "err"
+       };
+
+       syntax_define (syntax, false, false, "/*",  "*/", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "//",  "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "'",   "'",  '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"",  "\"", '\\', language->string_colour,    language->string_effect);
+       syntax_define (syntax, false, false, "`",   "`",  '\0', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       for (ulong word = 0; word < array_length (types); ++word) {
+               syntax_define (syntax, false, true, types [word], separators, '\0', language->type_colour, language->type_effect);
+       }
+
+       for (ulong word = 0; word < array_length (commons); ++word) {
+               syntax_define (syntax, false, true, commons [word], separators, '\0', language->extension_colour, language->extension_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]{}",             "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+*-/%!&~^?|", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/haskell.h b/xanguage/haskell.h
new file mode 100755 (executable)
index 0000000..5766d29
--- /dev/null
@@ -0,0 +1,34 @@
+static void language_highlight_haskell (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/%!@#$&~^?|()[]{}'\" \t\r\n";
+
+       const char * keywords [] = {
+               "case",         "class",        "data",         "deriving",     "do",           "else",         "if",           "import",
+               "in",           "infix",        "infixl",       "infixr",       "instance",     "let",          "of",           "module",
+               "newtype",      "then",         "type",         "where"
+       };
+
+       const char * types [] = {
+               "Int",          "Integer",      "String",       "Char",         "Float",        "Boolean"
+       };
+
+       syntax_define (syntax, false, false, "{-",  "-}", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "--",  "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "'",   "'",  '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"",  "\"", '\\', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       for (ulong word = 0; word < array_length (types); ++word) {
+               syntax_define (syntax, false, true, types [word], separators, '\0', language->type_colour, language->type_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]{}",                "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+*-/%!@#$&~^?|", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/lua.h b/xanguage/lua.h
new file mode 100755 (executable)
index 0000000..1509e86
--- /dev/null
@@ -0,0 +1,50 @@
+static void language_highlight_lua (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/%~^#|()[]{}'\" \t\r\n";
+
+       const char * keywords [] = {
+               "and",          "break",        "do",           "else",         "elseif",       "end",          "false",        "for",
+               "function",     "if",           "in",           "local",        "nil",          "not",          "or",           "until",
+               "repeat",       "return",       "then",         "true",         "while"
+       };
+
+       const char * types [] = {
+               "boolean",      "number",       "string",       "userdata",     "function",     "thread",       "table"
+       };
+
+       const char * commons [] = {
+               "require",      "print",        "seek",         "dofile",       "loadfile",     "assert",       "rawset",       "rawget",
+               "setfenv",      "pairs",        "ipairs",       "tonumber",     "tostring",     "foreach",      "setn",         "getn",
+               "insert",       "concat",       "sort",         "remove",       "abs",          "ceil",         "floor",        "log10",
+               "rad",          "sqrt",         "acos",         "cos",          "fmod",         "max",          "random",       "tan",
+               "asin",         "cosh",         "frexp",        "min",          "randomseed",   "tanh",         "atan",         "deg",
+               "ldexp",        "modf",         "sin",          "atan2",        "sinh",         "exp",          "log",          "pow",
+               "open",         "close",        "read",         "write",        "input",        "output",       "format",       "lines",
+               "upper",        "lower",        "find",         "gfind",        "match",        "gmatch",       "sub",          "gsub",
+               "len",          "rep",          "char",         "dump",         "reverse",      "byte"
+       };
+
+       syntax_define (syntax, false, false, "--[[",  "]]", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "--",    "\n", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "'",     "'",  '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"",    "\"", '\\', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       for (ulong word = 0; word < array_length (types); ++word) {
+               syntax_define (syntax, false, true, types [word], separators, '\0', language->type_colour, language->type_effect);
+       }
+
+       for (ulong word = 0; word < array_length (commons); ++word) {
+               syntax_define (syntax, false, true, commons [word], separators, '\0', language->extension_colour, language->extension_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]{}",           "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+-*/%~^#|", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/pascal.h b/xanguage/pascal.h
new file mode 100755 (executable)
index 0000000..21bac25
--- /dev/null
@@ -0,0 +1,29 @@
+static void language_highlight_pascal (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/&@#$%^()[] \t\r\n";
+
+       const char * keywords [] = {
+               "absolute",     "and",          "array",        "asm",          "begin",        "case",         "const",        "constructor",
+               "destructor",   "div",          "do",           "downto",       "else",         "end",          "file",         "for",
+               "function",     "goto",         "if",           "in",           "inherited",    "inline",       "interface",    "xor",
+               "label",        "mod",          "nil",          "not",          "object",       "of",           "operator",     "or",
+               "packed",       "procedure",    "program",      "record",       "reintroduce",  "repeat",       "self",         "set",
+               "shl",          "shr",          "string",       "then",         "to",           "type",         "unit",         "until",
+               "uses",         "var",          "while",        "with"
+       };
+
+       syntax_define (syntax, false, false, "//", "\n", '\0', language->comment_colour, language->comment_effect);
+       syntax_define (syntax, false, false, "(*", "*)", '\0', language->comment_colour, language->comment_effect);
+       syntax_define (syntax, false, false, "{",  "}",  '\0', language->comment_colour, language->comment_effect);
+       syntax_define (syntax, false, false, "'",  "'",  '#',  language->string_colour,  language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       syntax_define (syntax, true, false, "[]()",              "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+-*/&@#$%^", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,    language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour, language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour, language->uppercase_effect);
+}
diff --git a/xanguage/python.h b/xanguage/python.h
new file mode 100755 (executable)
index 0000000..ccd8dcd
--- /dev/null
@@ -0,0 +1,47 @@
+static void language_highlight_python (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/%!&~^?|()[]{}'\" \t\r\n";
+
+       const char * keywords [] = {
+               "and",          "as",           "assert",       "break",        "class",        "continue",     "def",          "del",
+               "elif",         "else",         "except",       "False",        "finally",      "for",          "from",         "global",
+               "if",           "import",       "in",           "is",           "labmda",       "None",         "nonlocal",     "not",
+               "or",           "pass",         "raise",        "return",       "True",         "try",          "while",        "with",
+               "yield",        "async",        "await"
+       };
+
+       const char * subkeywords [] = {
+               "abs",          "all",          "any",          "apply",        "ascii",        "basestring",   "bin",          "bool",
+               "breakpoint",   "buffer",       "bytearray",    "bytes",        "callable",     "chr",          "classmethod",  "cmp",
+               "coerce",       "compile",      "complex",      "copyright",    "credits",      "delattr",      "dict",         "dir",
+               "divmod",       "enumerate",    "eval",         "execfile",     "exit",         "file",         "filter",       "float",
+               "format",       "frozenset",    "getattr",      "globals",      "hasattr",      "hash",         "help",         "hex",
+               "id",           "input",        "int",          "intern",       "isinstance",   "issubclass",   "iter",         "len",
+               "license",      "list",         "locals",       "long",         "map",          "max",          "memoryview",   "min",
+               "next",         "object",       "oct",          "open",         "ord",          "pow",          "property",     "quit",
+               "range",        "raw_input",    "reduce",       "reload",       "repr",         "reversed",     "round",        "set",
+               "setattr",      "slice",        "sorted",       "staticmethod", "str",          "sum",          "super",        "tuple",
+               "type",         "unichr",       "unicode",      "vars",         "xrange",       "zip"
+       };
+
+       syntax_define (syntax, false, false, "#",       "\n",     '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "'''",     "'''",    '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "\"\"\"",  "\"\"\"", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "'",       "'",      '\\', language->character_colour, language->character_effect);
+       syntax_define (syntax, false, false, "\"",      "\"",     '\\', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separators, '\0', language->keyword_colour, language->keyword_effect);
+       }
+
+       for (ulong word = 0; word < array_length (subkeywords); ++word) {
+               syntax_define (syntax, false, true, subkeywords [word], separators, '\0', language->extension_colour, language->extension_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]",               "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+*-/%!&~^?|", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 separators, '\0', language->number_colour,     language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators, '\0', language->lowercase_colour,  language->lowercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators, '\0', language->uppercase_colour,  language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators, '\0', language->underscore_colour, language->underscore_effect);
+}
diff --git a/xanguage/valgrind.h b/xanguage/valgrind.h
new file mode 100755 (executable)
index 0000000..411f580
--- /dev/null
@@ -0,0 +1,25 @@
+static void language_highlight_valgrind (language_structure * language, syntax_structure * syntax) {
+       const char * separators = ".,:;<=>+-*/%!&~^?|@#$()[]{}'\" \t\r\n";
+
+       const char * titles [] = {
+               //~"exit",         "set",          "elif",         "done",         "in",           "then",         "function",     "fi",
+               "HEAP",         "LEAK",         "ERROR",        "SUMMARY"
+       };
+
+       syntax_define (syntax, false, false, "==",  "==", '\0', language->comment_colour,   language->comment_effect);
+       syntax_define (syntax, false, false, "\"",  "\"", '\0', language->string_colour,    language->string_effect);
+       syntax_define (syntax, false, false, "(",   ")",  '\0', language->lowercase_colour, language->lowercase_effect);
+       syntax_define (syntax, false, false, "0x",  ":",  '\0', language->string_colour,    language->string_effect);
+
+       for (ulong word = 0; word < array_length (titles); ++word) {
+               syntax_define (syntax, false, true, titles [word], separators, '\0', language->fatal_colour, language->fatal_effect);
+       }
+
+       syntax_define (syntax, true, false, "()[]{}",                "", '\0', language->bracket_colour,  language->bracket_effect);
+       syntax_define (syntax, true, false, ".,:;<=>+*-/%!&~^?|@#$", "", '\0', language->operator_colour, language->operator_effect);
+
+       syntax_define (syntax, true, true, "0123456789",                 ": ()\t\r\n", '\0', language->number_colour,    language->number_effect);
+       syntax_define (syntax, true, true, "abcdefghijklmnopqrstuvwxyz", separators,   '\0', language->uppercase_colour, language->uppercase_effect);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separators,   '\0', language->uppercase_colour, language->uppercase_effect);
+       syntax_define (syntax, true, true, "_",                          separators,   '\0', language->uppercase_colour, language->uppercase_effect);
+}
diff --git a/xanual/adc.md b/xanual/adc.md
new file mode 100755 (executable)
index 0000000..c70de61
--- /dev/null
@@ -0,0 +1,52 @@
+# ADC — Add with Carry
+
+## Description
+
+Adds the destination operand (first operand), the source operand (second operand), and the carry (CF) flag and stores the result in the
+destination operand. The destination operand can be a register or a memory location; the source operand can be an immediate, a register, or a
+memory location. However, two memory operands cannot be used in one instruction. The state of the CF flag represents a carry from a previous
+addition. When an immediate value is used as an operand, it is sign-extended to the length of the destination operand format.
+
+## Instruction
+
+| Opcode           | Assembly         | Op/En | Modern Mode | Legacy Mode | Description                                                        |
+|------------------|------------------|-------|-------------|-------------|--------------------------------------------------------------------|
+| 14 ib            | ADC AL, imm8     | I     | Valid       | Valid       | Add with carry imm8 to AL.                                         |
+| 15 iw            | ADC AX, imm16    | I     | Valid       | Valid       | Add with carry imm16 to AX.                                        |
+| 15 id            | ADC EAX, imm32   | I     | Valid       | Valid       | Add with carry imm32 to EAX.                                       |
+| REX.W + 15 id    | ADC RAX, imm32   | I     | Valid       | N.E.        | Add with carry imm32 sign extended to 64-bits to RAX.              |
+| 80 /2 ib         | ADC r/m8, imm8   | MI    | Valid       | Valid       | Add with carry imm8 to r/m8.                                       |
+| REX + 80 /2 ib   | ADC r/m8*, imm8  | MI    | Valid       | N.E.        | Add with carry imm8 to r/m8.                                       |
+| 81 /2 iw         | ADC r/m16, imm16 | MI    | Valid       | Valid       | Add with carry imm16 to r/m16.                                     |
+| 81 /2 id         | ADC r/m32, imm32 | MI    | Valid       | Valid       | Add with CF imm32 to r/m32.                                        |
+| REX.W + 81 /2 id | ADC r/m64, imm32 | MI    | Valid       | N.E.        | Add with CF imm32 sign extended to 64-bits to r/m64.               |
+| 83 /2 ib         | ADC r/m16, imm8  | MI    | Valid       | Valid       | Add with CF sign-extended imm8 to r/m16.                           |
+| 83 /2 ib         | ADC r/m32, imm8  | MI    | Valid       | Valid       | Add with CF sign-extended imm8 into r/m32.                         |
+| REX.W + 83 /2 ib | ADC r/m64, imm8  | MI    | Valid       | N.E.        | Add with CF sign-extended imm8 into r/m64.                         |
+| 10 /r            | ADC r/m8, r8     | MR    | Valid       | Valid       | Add with carry byte register to r/m8.                              |
+| REX + 10 /r      | ADC r/m8*, r8*   | MR    | Valid       | N.E.        | Add with carry byte register to r/m64.                             |
+| 11 /r            | ADC r/m16, r16   | MR    | Valid       | Valid       | Add with carry r16 to r/m16.                                       |
+| 11 /r            | ADC r/m32, r32   | MR    | Valid       | Valid       | Add with CF r32 to r/m32.                                          |
+| REX.W + 11 /r    | ADC r/m64, r64   | MR    | Valid       | N.E.        | Add with CF r64 to r/m64.                                          |
+| 12 /r            | ADC r8, r/m8     | RM    | Valid       | Valid       | Add with carry r/m8 to byte register.                              |
+| REX + 12 /r      | ADC r8*, r/m8*   | RM    | Valid       | N.E.        | Add with carry r/m64 to byte register.                             |
+| 13 /r            | ADC r16, r/m16   | RM    | Valid       | Valid       | Add with carry r/m16 to r16.                                       |
+| 13 /r            | ADC r32, r/m32   | RM    | Valid       | Valid       | Add with CF r/m32 to r32.                                          |
+| REX.W + 13 /r    | ADC r64, r/m64   | RM    | Valid       | N.E.        | Add with CF r/m64 to r64.                                          |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
+
+The ADC instruction does not distinguish between signed or unsigned operands. Instead, the processor evaluates the result for both data types
+and sets the OF and CF flags to indicate a carry in the signed or unsigned result, respectively. The SF flag indicates the sign of the signed
+result.
+
+The ADC instruction is usually executed as part of a multibyte or multiword addition in which an ADD instruction is followed by an ADC
+instruction.
+
+In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional
+registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this
+section for encoding data and limits.
diff --git a/xanual/add.md b/xanual/add.md
new file mode 100755 (executable)
index 0000000..5460984
--- /dev/null
@@ -0,0 +1,48 @@
+# ADD — Add
+
+## Description
+
+Adds the destination operand (first operand) and the source operand (second operand) and then stores the result in the destination operand. The
+destination operand can be a register or a memory location; the source operand can be an immediate, a register, or a memory location. However,
+two memory operands cannot be used in one instruction. When an immediate value is used as an operand, it is sign-extended to the length of the
+destination operand format.
+
+## Instruction
+
+| Opcode           | Assembly         | Op/En | Modern Mode | Legacy Mode | Description                                                        |
+|------------------|------------------|-------|-------------|-------------|--------------------------------------------------------------------|
+| 04 ib            | ADD AL, imm8     | I     | Valid       | Valid       | Add imm8 to AL.                                                    |
+| 05 iw            | ADD AX, imm16    | I     | Valid       | Valid       | Add imm16 to AX.                                                   |
+| 05 id            | ADD EAX, imm32   | I     | Valid       | Valid       | Add imm32 to EAX.                                                  |
+| REX.W + 05 id    | ADD RAX, imm32   | I     | Valid       | N.E.        | Add imm32 sign-extended to 64-bits to RAX.                         |
+| 80 /0 ib         | ADD r/m8, imm8   | MI    | Valid       | Valid       | Add imm8 to r/m8.                                                  |
+| REX + 80 /0 ib   | ADD r/m8*, imm8  | MI    | Valid       | N.E.        | Add sign-extended imm8 to r/m64.                                   |
+| 81 /0 iw         | ADD r/m16, imm16 | MI    | Valid       | Valid       | Add imm16 to r/m16.                                                |
+| 81 /0 id         | ADD r/m32, imm32 | MI    | Valid       | Valid       | Add imm32 to r/m32.                                                |
+| REX.W + 81 /0 id | ADD r/m64, imm32 | MI    | Valid       | N.E.        | Add imm32 sign-extended to 64-bits to r/m64.                       |
+| 83 /0 ib         | ADD r/m16, imm8  | MI    | Valid       | Valid       | Add sign-extended imm8 to r/m16.                                   |
+| 83 /0 ib         | ADD r/m32, imm8  | MI    | Valid       | Valid       | Add sign-extended imm8 to r/m32.                                   |
+| REX.W + 83 /0 ib | ADD r/m64, imm8  | MI    | Valid       | N.E.        | Add sign-extended imm8 to r/m64.                                   |
+| 00 /r            | ADD r/m8, r8     | MR    | Valid       | Valid       | Add r8 to r/m8.                                                    |
+| REX + 00 /r      | ADD r/m8*, r8*   | MR    | Valid       | N.E.        | Add r8 to r/m8.                                                    |
+| 01 /r            | ADD r/m16, r16   | MR    | Valid       | Valid       | Add r16 to r/m16.                                                  |
+| 01 /r            | ADD r/m32, r32   | MR    | Valid       | Valid       | Add r32 to r/m32.                                                  |
+| REX.W + 01 /r    | ADD r/m64, r64   | MR    | Valid       | N.E.        | Add r64 to r/m64.                                                  |
+| 02 /r            | ADD r8, r/m8     | RM    | Valid       | Valid       | Add r/m8 to r8.                                                    |
+| REX + 02 /r      | ADD r8*, r/m8*   | RM    | Valid       | N.E.        | Add r/m8 to r8.                                                    |
+| 03 /r            | ADD r16, r/m16   | RM    | Valid       | Valid       | Add r/m16 to r16.                                                  |
+| 03 /r            | ADD r32, r/m32   | RM    | Valid       | Valid       | Add r/m32 to r32.                                                  |
+| REX.W + 03 /r    | ADD r64, r/m64   | RM    | Valid       | N.E.        | Add r/m64 to r64.                                                  |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
+
+The ADD instruction performs integer addition. It evaluates the result for both signed and unsigned integer operands and sets the CF and OF
+flags to indicate a carry (overflow) in the signed or unsigned result, respectively. The SF flag indicates the sign of the signed result.
+
+In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional
+registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this
+section for encoding data and limits.
diff --git a/xanual/and.md b/xanual/and.md
new file mode 100755 (executable)
index 0000000..ce79ef2
--- /dev/null
@@ -0,0 +1,45 @@
+# AND — Logical And
+
+## Description
+
+Performs a bitwise AND operation on the destination (first) and source (second) operands and stores the result in the destination operand
+location. The source operand can be an immediate, a register, or a memory location; the destination operand can be a register or a memory
+location. However, two memory operands cannot be used in one instruction. Each bit of the result is set to 1 if both corresponding bits of the
+first and second operands are 1; otherwise, it is set to 0.
+
+## Instruction
+
+| Opcode           | Assembly         | Op/En | Modern Mode | Legacy Mode | Description                                                        |
+|------------------|------------------|-------|-------------|-------------|--------------------------------------------------------------------|
+| 24 ib            | AND AL, imm8     | I     | Valid       | Valid       | AL AND imm8.                                                       |
+| 25 iw            | AND AX, imm16    | I     | Valid       | Valid       | AX AND imm16.                                                      |
+| 25 id            | AND EAX, imm32   | I     | Valid       | Valid       | EAX AND imm32.                                                     |
+| REX.W + 25 id    | AND RAX, imm32   | I     | Valid       | N.E.        | RAX AND imm32 sign-extended to 64-bits.                            |
+| 80 /4 ib         | AND r/m8, imm8   | MI    | Valid       | Valid       | r/m8 AND imm8.                                                     |
+| REX + 80 /4 ib   | AND r/m8*, imm8  | MI    | Valid       | N.E.        | r/m8 AND imm8.                                                     |
+| 81 /4 iw         | AND r/m16, imm16 | MI    | Valid       | Valid       | r/m16 AND imm16.                                                   |
+| 81 /4 id         | AND r/m32, imm32 | MI    | Valid       | Valid       | r/m32 AND imm32.                                                   |
+| REX.W + 81 /4 id | AND r/m64, imm32 | MI    | Valid       | N.E.        | r/m64 AND imm32 sign extended to 64-bits.                          |
+| 83 /4 ib         | AND r/m16, imm8  | MI    | Valid       | Valid       | r/m16 AND imm8 (sign-extended).                                    |
+| 83 /4 ib         | AND r/m32, imm8  | MI    | Valid       | Valid       | r/m32 AND imm8 (sign-extended).                                    |
+| REX.W + 83 /4 ib | AND r/m64, imm8  | MI    | Valid       | N.E.        | r/m64 AND imm8 (sign-extended).                                    |
+| 20 /r            | AND r/m8, r8     | MR    | Valid       | Valid       | r/m8 AND r8.                                                       |
+| REX + 20 /r      | AND r/m8*, r8*   | MR    | Valid       | N.E.        | r/m64 AND r8 (sign-extended).                                      |
+| 21 /r            | AND r/m16, r16   | MR    | Valid       | Valid       | r/m16 AND r16.                                                     |
+| 21 /r            | AND r/m32, r32   | MR    | Valid       | Valid       | r/m32 AND r32.                                                     |
+| REX.W + 21 /r    | AND r/m64, r64   | MR    | Valid       | N.E.        | r/m64 AND r32.                                                     |
+| 22 /r            | AND r8, r/m8     | RM    | Valid       | Valid       | r8 AND r/m8.                                                       |
+| REX + 22 /r      | AND r8*, r/m8*   | RM    | Valid       | N.E.        | r/m64 AND r8 (sign-extended).                                      |
+| 23 /r            | AND r16, r/m16   | RM    | Valid       | Valid       | r16 AND r/m16.                                                     |
+| 23 /r            | AND r32, r/m32   | RM    | Valid       | Valid       | r32 AND r/m32.                                                     |
+| REX.W + 23 /r    | AND r64, r/m64   | RM    | Valid       | N.E.        | r64 AND r/m64.                                                     |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the it to be executed atomically.
+
+In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional
+registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this
+section for encoding data and limits.
diff --git a/xanual/call.md b/xanual/call.md
new file mode 100755 (executable)
index 0000000..da34cdd
--- /dev/null
@@ -0,0 +1,201 @@
+# CALL — Call Procedure
+
+## Description
+
+Saves procedure linking information on the stack and branches to the called procedure specified using the target operand. The target operand
+specifies the address of the first instruction in the called procedure. The operand can be an immediate value, a general-purpose register, or a
+memory location.
+
+## Instruction
+
+| Opcode        | Assembly      | Op/En | Modern Mode | Legacy Mode | Description                                                              |
+|---------------|---------------|-------|-------------|-------------|--------------------------------------------------------------------------|
+| E8 cw         | CALL rel16    | M     | N.S.        | Valid       | Call near, relative, displacement relative to next instruction.          |
+| E8 cd         | CALL rel32    | M     | Valid       | Valid       | Call near, relative, displacement relative to next instruction, extend.  |
+| FF /2         | CALL r/m16    | M     | N.E.        | Valid       | Call near, absolute indirect, address given in r/m16.                    |
+| FF /2         | CALL r/m32    | M     | N.E.        | Valid       | Call near, absolute indirect, address given in r/m32.                    |
+| FF /2         | CALL r/m64    | M     | Valid       | N.E.        | Call near, absolute indirect, address given in r/m64.                    |
+| 9A cd         | CALL ptr16:16 | D     | Invalid     | Valid       | Call far, absolute, address given in operand.                            |
+| 9A cp         | CALL ptr16:32 | D     | Invalid     | Valid       | Call far, absolute, address given in operand.                            |
+| FF /3         | CALL m16:16   | M     | Valid       | Valid       | Call far, absolute indirect address given in m16:16, extend.             |
+| FF /3         | CALL m16:32   | M     | Valid       | Valid       | In 64-bit mode: If selector points to a gate, semi-extend.               |
+| REX.W + FF /3 | CALL m16:64   | M     | Valid       | N.E.        | In 64-bit mode: If selector points to a gate, semi-extend.               |
+
+## Information
+
+This instruction can be used to execute four types of calls:
+
+• Near Call — A call to a procedure in the current code segment (the segment currently pointed to by the CS register), sometimes referred to as
+an intra-segment call.
+
+• Far Call — A call to a procedure located in a different segment than the current code segment, sometimes referred to as an inter-segment
+call.
+
+• Inter-privilege-level far call — A far call to a procedure in a segment at a different privilege level than that of the currently executing
+program or procedure.
+
+• Task switch — A call to a procedure located in a different task.
+
+The latter two call types (inter-privilege-level call and task switch) can only be executed in protected mode.
+
+Near Call. When executing a near call, the processor pushes the value of the EIP register (which contains the offset of the instruction
+following the CALL instruction) on the stack (for use later as a return-instruction pointer). The processor then branches to the address in the
+current code segment specified by the target operand. The target operand specifies either an absolute offset in the code segment (an offset
+from the base of the code segment) or a relative offset (a signed displacement relative to the current value of the instruction pointer in the
+EIP register; this value points to the instruction following the CALL instruction). The CS register is not changed on near calls.
+
+For a near call absolute, an absolute offset is specified indirectly in a general-purpose register or a memory location (r/m16, r/m32, or
+r/m64). The operand-size attribute determines the size of the target operand (16, 32 or 64 bits). When in 64-bit mode, the operand size for
+near call (and all near branches) is forced to 64-bits. Absolute offsets are loaded directly into the EIP(RIP) register. If the operand size
+attribute is 16, the upper two bytes of the EIP register are cleared, resulting in a maximum instruction pointer size of 16 bits. When
+accessing an absolute offset indirectly using the stack pointer [ESP] as the base register, the base value used is the value of the ESP before
+the instruction executes.
+
+A relative offset (rel16 or rel32) is generally specified as a label in assembly code. But at the machine code level, it is encoded as a
+signed, 16- or 32-bit immediate value. This value is added to the value in the EIP(RIP) register. In 64-bit mode the relative offset is always
+a 32-bit immediate value which is sign extended to 64-bits before it is added to the value in the RIP register for the target calculation. As
+with absolute offsets, the operand-size attribute determines the size of the target operand (16, 32, or 64 bits). In 64-bit mode the target
+operand will always be 64- bits because the operand size is forced to 64-bits for near branches.
+
+Far Calls in Real-Address or Virtual-8086 Mode. When executing a far call in real- address or virtual-8086 mode, the processor pushes the
+current value of both the CS and EIP registers on the stack for use as a return-instruction pointer. The processor then performs a "far branch"
+to the code segment and offset specified with the target operand for the called procedure. The target operand specifies an absolute far address
+either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). With the pointer method, the
+segment and offset of the called procedure is encoded in the instruction using a 4-byte (16-bit operand size) or 6- byte (32-bit operand size)
+far address immediate. With the indirect method, the target operand specifies a memory location that contains a 4-byte (16-bit operand size) or
+6-byte (32-bit operand size) far address. The operand-size attribute determines the size of the offset (16 or 32 bits) in the far address. The
+far address is loaded directly into the CS and EIP registers. If the operand-size attribute is 16, the upper two bytes of the EIP register are
+cleared.
+
+Far Calls in Protected Mode. When the processor is operating in protected mode, the CALL instruction can be used to perform the following types
+of far calls:
+
+• Far call to the same privilege level
+• Far call to a different privilege level (inter-privilege level call)
+• Task switch (far call to another task)
+
+In protected mode, the processor always uses the segment selector part of the far address to access the corresponding descriptor in the GDT or
+LDT. The descriptor type (code segment, call gate, task gate, or TSS) and access rights determine the type of call operation to be performed.
+
+If the selected descriptor is for a code segment, a far call to a code segment at the same privilege level is performed. (If the selected code
+segment is at a different privilege level and the code segment is non-conforming, a general-protection exception is generated.) A far call to
+the same privilege level in protected mode is very similar to one carried out in real-address or virtual-8086 mode. The target operand
+specifies an absolute far address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or
+m16:32). The operand- size attribute determines the size of the offset (16 or 32 bits) in the far address. The new code segment selector and
+its descriptor are loaded into CS register; the offset from the instruction is loaded into the EIP register.
+
+A call gate (described in the next paragraph) can also be used to perform a far call to a code segment at the same privilege level. Using this
+mechanism provides an extra level of indirection and is the preferred method of making calls between 16-bit and 32-bit code segments.
+
+When executing an inter-privilege-level far call, the code segment for the procedure being called must be accessed through a call gate. The
+segment selector specified by the target operand identifies the call gate. The target operand can specify the call gate segment selector either
+directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). The processor obtains the segment
+selector for the new code segment and the new instruction pointer (offset) from the call gate descriptor. The offset from the target operand is
+ignored when a call gate is used.
+
+On inter-privilege-level calls, the processor switches to the stack for the privilege level of the called procedure. The segment selector for
+the new stack segment is specified in the TSS for the currently running task. The branch to the new code segment occurs after the stack switch.
+(Note that when using a call gate to perform a far call to a segment at the same privilege level, no stack switch occurs.) On the new stack,
+the processor pushes the segment selector and stack pointer for the calling procedure's stack, an optional set of parameters from the calling
+procedures stack, and the segment selector and instruction pointer for the calling procedure's code segment. A value in the call gate
+descriptor determines how many parameters to copy to the new stack. Finally, the processor branches to the address of the procedure being
+called within the new code segment.
+
+Executing a task switch with the CALL instruction is similar to executing a call through a call gate. The target operand specifies the segment
+selector of the task gate for the new task activated by the switch (the offset in the target operand is ignored). The task gate in turn points
+to the TSS for the new task, which contains the segment selectors for the task's code and stack segments. Note that the TSS also contains the
+EIP value for the next instruction that was to be executed before the calling task was suspended. This instruction pointer value is loaded into
+the EIP register to re-start the calling task.
+
+The CALL instruction can also specify the segment selector of the TSS directly, which eliminates the indirection of the task gate.
+
+When you execute at task switch with a CALL instruction, the nested task flag (NT) is set in the EFLAGS register and the new TSS's previous
+task link field is loaded with the old task's TSS selector. Code is expected to suspend this nested task by executing an IRET instruction
+which, because the NT flag is set, automatically uses the previous task link to return to the calling task. (See "Task Linking" in Chapter 7 of
+the Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 3A, for information on nested tasks.) Switching tasks with the CALL
+instruction differs in this regard from JMP instruction. JMP does not set the NT flag and therefore does not expect an IRET instruction to
+suspend the task.
+
+Mixing 16-Bit and 32-Bit Calls. When making far calls between 16-bit and 32-bit code segments, use a call gate. If the far call is from a
+32-bit code segment to a 16-bit code segment, the call should be made from the first 64 KBytes of the 32-bit code segment. This is because the
+operand-size attribute of the instruction is set to 16, so only a 16-bit return address offset can be saved. Also, the call should be made
+using a 16-bit call gate so that 16-bit values can be pushed on the stack.
+
+Far Calls in Compatibility Mode. When the processor is operating in compatibility mode, the CALL instruction can be used to perform the
+following types of far calls:
+
+• Far call to the same privilege level, remaining in compatibility mode
+• Far call to the same privilege level, transitioning to 64-bit mode
+• Far call to a different privilege level (inter-privilege level call), transitioning to 64-bit mode
+
+Note that a CALL instruction can not be used to cause a task switch in compatibility mode since task switches are not supported in IA-32e mode.
+
+In compatibility mode, the processor always uses the segment selector part of the far address to access the corresponding descriptor in the GDT
+or LDT. The descriptor type (code segment, call gate) and access rights determine the type of call operation to be performed.
+
+If the selected descriptor is for a code segment, a far call to a code segment at the same privilege level is performed. (If the selected code
+segment is at a different privilege level and the code segment is non-conforming, a general-protection exception is generated.) A far call to
+the same privilege level in compatibility mode is very similar to one carried out in protected mode. The target operand specifies an absolute
+far address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). The operand-size
+attribute determines the size of the offset (16 or 32 bits) in the far address. The new code segment selector and its descriptor are loaded
+into CS register and the offset from the instruction is loaded into the EIP register. The difference is that 64-bit mode may be entered. This
+specified by the L bit in the new code segment descriptor.
+
+Note that a 64-bit call gate (described in the next paragraph) can also be used to perform a far call to a code segment at the same privilege
+level. However, using this mechanism requires that the target code segment descriptor have the L bit set, causing an entry to 64-bit mode.
+
+When executing an inter-privilege-level far call, the code segment for the procedure being called must be accessed through a 64-bit call gate.
+The segment selector specified by the target operand identifies the call gate. The target operand can specify the call gate segment selector
+either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). The processor obtains the
+segment selector for the new code segment and the new instruction pointer (offset) from the 16-byte call gate descriptor. The offset from the
+target operand is ignored when a call gate is used.
+
+On inter-privilege-level calls, the processor switches to the stack for the privilege level of the called procedure. The segment selector for
+the new stack segment is set to NULL. The new stack pointer is specified in the TSS for the currently running task. The branch to the new code
+segment occurs after the stack switch. (Note that when using a call gate to perform a far call to a segment at the same privilege level, an
+implicit stack switch occurs as a result of entering 64-bit mode. The SS selector is unchanged, but stack segment accesses use a segment base
+of 0x0, the limit is ignored, and the default stack size is 64-bits. The full value of RSP is used for the offset, of which the upper 32-bits
+are undefined.) On the new stack, the processor pushes the segment selector and stack pointer for the calling procedure's stack and the segment
+selector and instruction pointer for the calling procedure's code segment. Parameter copy is not supported in IA-32e mode. Finally, the
+processor branches to the address of the procedure being called within the new code segment.
+
+Near/(Far) Calls in 64-bit Mode. When the processor is operating in 64-bit mode, the CALL instruction can be used to perform the following
+types of far calls:
+
+• Far call to the same privilege level, transitioning to compatibility mode
+• Far call to the same privilege level, remaining in 64-bit mode
+• Far call to a different privilege level (inter-privilege level call), remaining in 64-bit mode
+
+Note that in this mode the CALL instruction can not be used to cause a task switch in 64-bit mode since task switches are not supported in
+IA-32e mode.
+
+In 64-bit mode, the processor always uses the segment selector part of the far address to access the corresponding descriptor in the GDT or
+LDT. The descriptor type (code segment, call gate) and access rights determine the type of call operation to be performed.
+
+If the selected descriptor is for a code segment, a far call to a code segment at the same privilege level is performed. (If the selected code
+segment is at a different privilege level and the code segment is non-conforming, a general-protection exception is generated.) A far call to
+the same privilege level in 64-bit mode is very similar to one carried out in compatibility mode. The target operand specifies an absolute far
+address indirectly with a memory location (m16:16, m16:32 or m16:64). The form of CALL with a direct specification of absolute far address is
+not defined in 64-bit mode. The operand-size attribute determines the size of the offset (16, 32, or 64 bits) in the far address. The new code
+segment selector and its descriptor are loaded into the CS register; the offset from the instruction is loaded into the EIP register. The new
+code segment may specify entry either into compatibility or 64-bit mode, based on the L bit value.
+
+A 64-bit call gate (described in the next paragraph) can also be used to perform a far call to a code segment at the same privilege level.
+However, using this mechanism requires that the target code segment descriptor have the L bit set.
+
+When executing an inter-privilege-level far call, the code segment for the procedure being called must be accessed through a 64-bit call gate.
+The segment selector specified by the target operand identifies the call gate. The target operand can only specify the call gate segment
+selector indirectly with a memory location (m16:16, m16:32 or m16:64). The processor obtains the segment selector for the new code segment and
+the new instruction pointer (offset) from the 16-byte call gate descriptor. The offset from the target operand is ignored when a call gate is
+used.
+
+On inter-privilege-level calls, the processor switches to the stack for the privilege level of the called procedure. The segment selector for
+the new stack segment is set to NULL. The new stack pointer is specified in the TSS for the currently running task. The branch to the new code
+segment occurs after the stack switch.
+
+Note that when using a call gate to perform a far call to a segment at the same privilege level, an implicit stack switch occurs as a result of
+entering 64-bit mode. The SS selector is unchanged, but stack segment accesses use a segment base of 0x0, the limit is ignored, and the default
+stack size is 64-bits. (The full value of RSP is used for the offset.) On the new stack, the processor pushes the segment selector and stack
+pointer for the calling procedure's stack and the segment selector and instruction pointer for the calling procedure's code segment. (Parameter
+copy is not supported in IA-32e mode.) Finally, the processor branches to the address of the procedure being called within the new code
+segment.
diff --git a/xanual/cmovcc.md b/xanual/cmovcc.md
new file mode 100755 (executable)
index 0000000..8530e76
--- /dev/null
@@ -0,0 +1,121 @@
+# CMOVcc — Conditional Move
+
+## Description
+
+The CMOVcc instructions check the state of one or more of the status flags in the EFLAGS register (CF, OF, PF, SF, and ZF) and perform a move
+operation if the flags are in a specified state (or condition). A condition code (cc) is associated with each instruction to indicate the
+condition being tested for. If the condition is not satisfied, a move is not performed and execution continues with the instruction following
+the CMOVcc instruction.
+
+## Instruction
+
+| Opcode           | Assembly           | Op/En | Modern Mode | Legacy Mode | Description                                                      |
+|------------------|--------------------|-------|-------------|-------------|------------------------------------------------------------------|
+| 0F 47 /r         | CMOVA r16, r/m16   | RM    | Valid       | Valid       | Move if above (CF=0 and ZF=0).                                   |
+| 0F 47 /r         | CMOVA r32, r/m32   | RM    | Valid       | Valid       | Move if above (CF=0 and ZF=0).                                   |
+| REX.W + 0F 47 /r | CMOVA r64, r/m64   | RM    | Valid       | N.E.        | Move if above (CF=0 and ZF=0).                                   |
+| 0F 43 /r         | CMOVAE r16, r/m16  | RM    | Valid       | Valid       | Move if above or equal (CF=0).                                   |
+| 0F 43 /r         | CMOVAE r32, r/m32  | RM    | Valid       | Valid       | Move if above or equal (CF=0).                                   |
+| REX.W + 0F 43 /r | CMOVAE r64, r/m64  | RM    | Valid       | N.E.        | Move if above or equal (CF=0).                                   |
+| 0F 42 /r         | CMOVB r16, r/m16   | RM    | Valid       | Valid       | Move if below (CF=1).                                            |
+| 0F 42 /r         | CMOVB r32, r/m32   | RM    | Valid       | Valid       | Move if below (CF=1).                                            |
+| REX.W + 0F 42 /r | CMOVB r64, r/m64   | RM    | Valid       | N.E.        | Move if below (CF=1).                                            |
+| 0F 46 /r         | CMOVBE r16, r/m16  | RM    | Valid       | Valid       | Move if below or equal (CF=1 or ZF=1).                           |
+| 0F 46 /r         | CMOVBE r32, r/m32  | RM    | Valid       | Valid       | Move if below or equal (CF=1 or ZF=1).                           |
+| REX.W + 0F 46 /r | CMOVBE r64, r/m64  | RM    | Valid       | N.E.        | Move if below or equal (CF=1 or ZF=1).                           |
+| 0F 42 /r         | CMOVC r16, r/m16   | RM    | Valid       | Valid       | Move if carry (CF=1).                                            |
+| 0F 42 /r         | CMOVC r32, r/m32   | RM    | Valid       | Valid       | Move if carry (CF=1).                                            |
+| REX.W + 0F 42 /r | CMOVC r64, r/m64   | RM    | Valid       | N.E.        | Move if carry (CF=1).                                            |
+| 0F 44 /r         | CMOVE r16, r/m16   | RM    | Valid       | Valid       | Move if equal (ZF=1).                                            |
+| 0F 44 /r         | CMOVE r32, r/m32   | RM    | Valid       | Valid       | Move if equal (ZF=1).                                            |
+| REX.W + 0F 44 /r | CMOVE r64, r/m64   | RM    | Valid       | N.E.        | Move if equal (ZF=1).                                            |
+| 0F 4F /r         | CMOVG r16, r/m16   | RM    | Valid       | Valid       | Move if greater (ZF=0 and SF=OF).                                |
+| 0F 4F /r         | CMOVG r32, r/m32   | RM    | Valid       | Valid       | Move if greater (ZF=0 and SF=OF).                                |
+| REX.W + 0F 4F /r | CMOVG r64, r/m64   | RM    | Valid       | N.E.        | Move if greater (ZF=0 and SF=OF).                                |
+| 0F 4D /r         | CMOVGE r16, r/m16  | RM    | Valid       | Valid       | Move if greater or equal (SF=OF).                                |
+| 0F 4D /r         | CMOVGE r32, r/m32  | RM    | Valid       | Valid       | Move if greater or equal (SF=OF).                                |
+| REX.W + 0F 4D /r | CMOVGE r64, r/m64  | RM    | Valid       | N.E.        | Move if greater or equal (SF=OF).                                |
+| 0F 4C /r         | CMOVL r16, r/m16   | RM    | Valid       | Valid       | Move if less (SF≠ OF).                                           |
+| 0F 4C /r         | CMOVL r32, r/m32   | RM    | Valid       | Valid       | Move if less (SF≠ OF).                                           |
+| REX.W + 0F 4C /r | CMOVL r64, r/m64   | RM    | Valid       | N.E.        | Move if less (SF≠ OF).                                           |
+| 0F 4E /r         | CMOVLE r16, r/m16  | RM    | Valid       | Valid       | Move if less or equal (ZF=1 or SF≠ OF).                          |
+| 0F 4E /r         | CMOVLE r32, r/m32  | RM    | Valid       | Valid       | Move if less or equal (ZF=1 or SF≠ OF).                          |
+| REX.W + 0F 4E /r | CMOVLE r64, r/m64  | RM    | Valid       | N.E.        | Move if less or equal (ZF=1 or SF≠ OF).                          |
+| 0F 46 /r         | CMOVNA r16, r/m16  | RM    | Valid       | Valid       | Move if not above (CF=1 or ZF=1).                                |
+| 0F 46 /r         | CMOVNA r32, r/m32  | RM    | Valid       | Valid       | Move if not above (CF=1 or ZF=1).                                |
+| REX.W + 0F 46 /r | CMOVNA r64, r/m64  | RM    | Valid       | N.E.        | Move if not above (CF=1 or ZF=1).                                |
+| 0F 42 /r         | CMOVNAE r16, r/m16 | RM    | Valid       | Valid       | Move if not above or equal (CF=1).                               |
+| 0F 42 /r         | CMOVNAE r32, r/m32 | RM    | Valid       | Valid       | Move if not above or equal (CF=1).                               |
+| REX.W + 0F 42 /r | CMOVNAE r64, r/m64 | RM    | Valid       | N.E.        | Move if not above or equal (CF=1).                               |
+| 0F 43 /r         | CMOVNB r16, r/m16  | RM    | Valid       | Valid       | Move if not below (CF=0).                                        |
+| 0F 43 /r         | CMOVNB r32, r/m32  | RM    | Valid       | Valid       | Move if not below (CF=0).                                        |
+| REX.W + 0F 43 /r | CMOVNB r64, r/m64  | RM    | Valid       | N.E.        | Move if not below (CF=0).                                        |
+| 0F 47 /r         | CMOVNBE r16, r/m16 | RM    | Valid       | Valid       | Move if not below or equal (CF=0 and ZF=0).                      |
+| 0F 47 /r         | CMOVNBE r32, r/m32 | RM    | Valid       | Valid       | Move if not below or equal (CF=0 and ZF=0).                      |
+| REX.W + 0F 47 /r | CMOVNBE r64, r/m64 | RM    | Valid       | N.E.        | Move if not below or equal (CF=0 and ZF=0).                      |
+| 0F 43 /r         | CMOVNC r16, r/m16  | RM    | Valid       | Valid       | Move if not carry (CF=0).                                        |
+| 0F 43 /r         | CMOVNC r32, r/m32  | RM    | Valid       | Valid       | Move if not carry (CF=0).                                        |
+| REX.W + 0F 43 /r | CMOVNC r64, r/m64  | RM    | Valid       | N.E.        | Move if not carry (CF=0).                                        |
+| 0F 45 /r         | CMOVNE r16, r/m16  | RM    | Valid       | Valid       | Move if not equal (ZF=0).                                        |
+| 0F 45 /r         | CMOVNE r32, r/m32  | RM    | Valid       | Valid       | Move if not equal (ZF=0).                                        |
+| REX.W + 0F 45 /r | CMOVNE r64, r/m64  | RM    | Valid       | N.E.        | Move if not equal (ZF=0).                                        |
+| 0F 4E /r         | CMOVNG r16, r/m16  | RM    | Valid       | Valid       | Move if not greater (ZF=1 or SF≠ OF).                            |
+| 0F 4E /r         | CMOVNG r32, r/m32  | RM    | Valid       | Valid       | Move if not greater (ZF=1 or SF≠ OF).                            |
+| REX.W + 0F 4E /r | CMOVNG r64, r/m64  | RM    | Valid       | N.E.        | Move if not greater (ZF=1 or SF≠ OF).                            |
+| 0F 4C /r         | CMOVNGE r16, r/m16 | RM    | Valid       | Valid       | Move if not greater or equal (SF≠ OF).                           |
+| 0F 4C /r         | CMOVNGE r32, r/m32 | RM    | Valid       | Valid       | Move if not greater or equal (SF≠ OF).                           |
+| REX.W + 0F 4C /r | CMOVNGE r64, r/m64 | RM    | Valid       | N.E.        | Move if not greater or equal (SF≠ OF).                           |
+| 0F 4D /r         | CMOVNL r16, r/m16  | RM    | Valid       | Valid       | Move if not less (SF=OF).                                        |
+| 0F 4D /r         | CMOVNL r32, r/m32  | RM    | Valid       | Valid       | Move if not less (SF=OF).                                        |
+| REX.W + 0F 4D /r | CMOVNL r64, r/m64  | RM    | Valid       | N.E.        | Move if not less (SF=OF).                                        |
+| 0F 4F /r         | CMOVNLE r16, r/m16 | RM    | Valid       | Valid       | Move if not less or equal (ZF=0 and SF=OF).                      |
+| 0F 4F /r         | CMOVNLE r32, r/m32 | RM    | Valid       | Valid       | Move if not less or equal (ZF=0 and SF=OF).                      |
+| REX.W + 0F 4F /r | CMOVNLE r64, r/m64 | RM    | Valid       | N.E.        | Move if not less or equal (ZF=0 and SF=OF).                      |
+| 0F 41 /r         | CMOVNO r16, r/m16  | RM    | Valid       | Valid       | Move if not overflow (OF=0).                                     |
+| 0F 41 /r         | CMOVNO r32, r/m32  | RM    | Valid       | Valid       | Move if not overflow (OF=0).                                     |
+| REX.W + 0F 41 /r | CMOVNO r64, r/m64  | RM    | Valid       | N.E.        | Move if not overflow (OF=0).                                     |
+| 0F 4B /r         | CMOVNP r16, r/m16  | RM    | Valid       | Valid       | Move if not parity (PF=0).                                       |
+| 0F 4B /r         | CMOVNP r32, r/m32  | RM    | Valid       | Valid       | Move if not parity (PF=0).                                       |
+| REX.W + 0F 4B /r | CMOVNP r64, r/m64  | RM    | Valid       | N.E.        | Move if not parity (PF=0).                                       |
+| 0F 49 /r         | CMOVNS r16, r/m16  | RM    | Valid       | Valid       | Move if not sign (SF=0).                                         |
+| 0F 49 /r         | CMOVNS r32, r/m32  | RM    | Valid       | Valid       | Move if not sign (SF=0).                                         |
+| REX.W + 0F 49 /r | CMOVNS r64, r/m64  | RM    | Valid       | N.E.        | Move if not sign (SF=0).                                         |
+| 0F 45 /r         | CMOVNZ r16, r/m16  | RM    | Valid       | Valid       | Move if not zero (ZF=0).                                         |
+| 0F 45 /r         | CMOVNZ r32, r/m32  | RM    | Valid       | Valid       | Move if not zero (ZF=0).                                         |
+| REX.W + 0F 45 /r | CMOVNZ r64, r/m64  | RM    | Valid       | N.E.        | Move if not zero (ZF=0).                                         |
+| 0F 40 /r         | CMOVO r16, r/m16   | RM    | Valid       | Valid       | Move if overflow (OF=1).                                         |
+| 0F 40 /r         | CMOVO r32, r/m32   | RM    | Valid       | Valid       | Move if overflow (OF=1).                                         |
+| REX.W + 0F 40 /r | CMOVO r64, r/m64   | RM    | Valid       | N.E.        | Move if overflow (OF=1).                                         |
+| 0F 4A /r         | CMOVP r16, r/m16   | RM    | Valid       | Valid       | Move if parity (PF=1).                                           |
+| 0F 4A /r         | CMOVP r32, r/m32   | RM    | Valid       | Valid       | Move if parity (PF=1).                                           |
+| REX.W + 0F 4A /r | CMOVP r64, r/m64   | RM    | Valid       | N.E.        | Move if parity (PF=1).                                           |
+| 0F 4A /r         | CMOVPE r16, r/m16  | RM    | Valid       | Valid       | Move if parity even (PF=1).                                      |
+| 0F 4A /r         | CMOVPE r32, r/m32  | RM    | Valid       | Valid       | Move if parity even (PF=1).                                      |
+| REX.W + 0F 4A /r | CMOVPE r64, r/m64  | RM    | Valid       | N.E.        | Move if parity even (PF=1).                                      |
+| 0F 4B /r         | CMOVPO r16, r/m16  | RM    | Valid       | Valid       | Move if parity odd (PF=0).                                       |
+| 0F 4B /r         | CMOVPO r32, r/m32  | RM    | Valid       | Valid       | Move if parity odd (PF=0).                                       |
+| REX.W + 0F 4B /r | CMOVPO r64, r/m64  | RM    | Valid       | N.E.        | Move if parity odd (PF=0).                                       |
+| 0F 48 /r         | CMOVS r16, r/m16   | RM    | Valid       | Valid       | Move if sign (SF=1).                                             |
+| 0F 48 /r         | CMOVS r32, r/m32   | RM    | Valid       | Valid       | Move if sign (SF=1).                                             |
+| REX.W + 0F 48 /r | CMOVS r64, r/m64   | RM    | Valid       | N.E.        | Move if sign (SF=1).                                             |
+| 0F 44 /r         | CMOVZ r16, r/m16   | RM    | Valid       | Valid       | Move if zero (ZF=1).                                             |
+| 0F 44 /r         | CMOVZ r32, r/m32   | RM    | Valid       | Valid       | Move if zero (ZF=1).                                             |
+| REX.W + 0F 44 /r | CMOVZ r64, r/m64   | RM    | Valid       | N.E.        | Move if zero (ZF=1).                                             |
+
+## Information
+
+These instructions can move 16-bit, 32-bit or 64-bit values from memory to a general-purpose register or from one general-purpose register to
+another. Conditional moves of 8-bit register operands are not supported.
+
+The condition for each CMOVcc mnemonic is given in the description column of the above table. The terms "less" and "greater" are used for
+comparisons of signed integers and the terms "above" and "below" are used for unsigned integers.
+
+Because a particular state of the status flags can sometimes be interpreted in two ways, two mnemonics are defined for some opcodes. For
+example, the CMOVA (conditional move if above) instruction and the CMOVNBE (conditional move if not below or equal) instruction are alternate
+mnemonics for the opcode 0F 47H.
+
+The CMOVcc instructions were introduced in P6 family processors; however, these instructions may not be supported by all IA-32 processors.
+Software can determine if the CMOVcc instructions are supported by checking the processor's feature information with the CPUID instruction.
+
+In 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.R prefix permits access to addi- tional registers (R8-R15).
+Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.
diff --git a/xanual/cmp.md b/xanual/cmp.md
new file mode 100755 (executable)
index 0000000..88eb3ff
--- /dev/null
@@ -0,0 +1,45 @@
+# CMP — Compare Two Operands
+
+## Description
+
+Compares the first source operand with the second source operand and sets the status flags in the EFLAGS register according to the results. The
+comparison is performed by subtracting the second operand from the first operand and then setting the status flags in the same manner as the
+SUB instruction. When an immediate value is used as an operand, it is sign-extended to the length of the first operand.
+
+## Instruction
+
+| Opcode           | Assembly         | Op/En | Modern Mode | Legacy Mode | Description                                                        |
+|------------------|------------------|-------|-------------|-------------|--------------------------------------------------------------------|
+| 3C ib            | CMP AL, imm8     | I     | Valid       | Valid       | Compare imm8 with AL.                                              |
+| 3D iw            | CMP AX, imm16    | I     | Valid       | Valid       | Compare imm16 with AX.                                             |
+| 3D id            | CMP EAX, imm32   | I     | Valid       | Valid       | Compare imm32 with EAX.                                            |
+| REX.W + 3D id    | CMP RAX, imm32   | I     | Valid       | N.E.        | Compare imm32 sign-extended to 64-bits with RAX.                   |
+| 80 /7 ib         | CMP r/m8, imm8   | MI    | Valid       | Valid       | Compare imm8 with r/m8.                                            |
+| REX + 80 /7 ib   | CMP r/m8*, imm8  | MI    | Valid       | N.E.        | Compare imm8 with r/m8.                                            |
+| 81 /7 iw         | CMP r/m16, imm16 | MI    | Valid       | Valid       | Compare imm16 with r/m16.                                          |
+| 81 /7 id         | CMP r/m32, imm32 | MI    | Valid       | Valid       | Compare imm32 with r/m32.                                          |
+| REX.W + 81 /7 id | CMP r/m64, imm32 | MI    | Valid       | N.E.        | Compare imm32 sign-extended to 64-bits with r/m64.                 |
+| 83 /7 ib         | CMP r/m16, imm8  | MI    | Valid       | Valid       | Compare imm8 with r/m16.                                           |
+| 83 /7 ib         | CMP r/m32, imm8  | MI    | Valid       | Valid       | Compare imm8 with r/m32.                                           |
+| REX.W + 83 /7 ib | CMP r/m64, imm8  | MI    | Valid       | N.E.        | Compare imm8 with r/m64.                                           |
+| 38 /r            | CMP r/m8, r8     | MR    | Valid       | Valid       | Compare r8 with r/m8.                                              |
+| REX + 38 /r      | CMP r/m8*, r8*   | MR    | Valid       | N.E.        | Compare r8 with r/m8.                                              |
+| 39 /r            | CMP r/m16, r16   | MR    | Valid       | Valid       | Compare r16 with r/m16.                                            |
+| 39 /r            | CMP r/m32, r32   | MR    | Valid       | Valid       | Compare r32 with r/m32.                                            |
+| REX.W + 39 /r    | CMP r/m64,r64    | MR    | Valid       | N.E.        | Compare r64 with r/m64.                                            |
+| 3A /r            | CMP r8, r/m8     | RM    | Valid       | Valid       | Compare r/m8 with r8.                                              |
+| REX + 3A /r      | CMP r8*, r/m8*   | RM    | Valid       | N.E.        | Compare r/m8 with r8.                                              |
+| 3B /r            | CMP r16, r/m16   | RM    | Valid       | Valid       | Compare r/m16 with r16.                                            |
+| 3B /r            | CMP r32, r/m32   | RM    | Valid       | Valid       | Compare r/m32 with r32.                                            |
+| REX.W + 3B /r    | CMP r64, r/m64   | RM    | Valid       | N.E.        | Compare r/m64 with r64.                                            |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+The condition codes used by the Jcc, CMOVcc, and SETcc instructions are based on the results of a CMP instruction. Appendix B, "EFLAGS
+Condition Codes", in the Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 1, shows the relationship of the status flags
+and the condition codes.
+
+In 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15).
+Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.
diff --git a/xanual/dec.md b/xanual/dec.md
new file mode 100755 (executable)
index 0000000..faa890b
--- /dev/null
@@ -0,0 +1,31 @@
+# DEC — Decrement by 1
+
+## Description
+
+Subtracts 1 from the destination operand, while preserving the state of the CF flag. The destination operand can be a register or a memory
+location. This instruction allows a loop counter to be updated without disturbing the CF flag. To perform a decrement operation that updates
+the CF flag, use a SUB instruction with an immediate operand of 1.
+
+## Instruction
+
+| Opcode        | Assembly  | Op/En | Modern Mode | Legacy Mode | Description                                                                  |
+|---------------|-----------|-------|-------------|-------------|------------------------------------------------------------------------------|
+| FE /1         | DEC r/m8  | M     | Valid       | Valid       | Decrement r/m byte by 1.                                                     |
+| REX + FE /1   | DEC r/m8* | M     | Valid       | N.E.        | Decrement r/m byte by 1.                                                     |
+| FF /1         | DEC r/m16 | M     | Valid       | Valid       | Decrement r/m word by 1.                                                     |
+| FF /1         | DEC r/m32 | M     | Valid       | Valid       | Decrement r/m doubleword by 1.                                               |
+| REX.W + FF /1 | DEC r/m64 | M     | Valid       | N.E.        | Decrement r/m quadword by 1.                                                 |
+| 48+ rw**      | DEC r16   | O     | N.E.        | Valid       | Decrement word register by 1.                                                |
+| 48+ rd        | DEC r32   | O     | N.E.        | Valid       | Decrement doubleword register by 1.                                          |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+- 40H through 47H are REX prefixes in 64-bit mode.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
+
+n 64-bit mode, DEC r16 and DEC r32 are not encodable (because opcodes 48H through 4FH are REX prefixes). Otherwise, the instruction’s 64-bit
+mode default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix
+promotes operation to 64 bits.
diff --git a/xanual/div.md b/xanual/div.md
new file mode 100755 (executable)
index 0000000..3407c95
--- /dev/null
@@ -0,0 +1,28 @@
+# DIV - Unsigned Divide
+
+## Description
+
+Divides unsigned the value in the AX, DX:AX, EDX:EAX, or RDX:RAX registers (dividend) by the source operand (divisor) and stores the result in
+the AX (AH:AL), DX:AX, EDX:EAX, or RDX:RAX registers. The source operand can be a general-purpose register or a memory location. The action of
+this instruction depends on the operand size (dividend/divisor). Division using 64-bit operand is available only in 64-bit mode.
+
+## Instruction
+
+| Opcode        | Assembly  | Op/En | Modern Mode | Legacy Mode | Description                                                                  |
+|---------------|-----------|-------|-------------|-------------|------------------------------------------------------------------------------|
+| F6 /6         | DIV r/m8  | M     | Valid       | Valid       | Unsigned divide AX by r/m8, result in AL=Quotient, AH=Remainder.             |
+| REX + F6 /6   | DIV r/m8* | M     | Valid       | N.E.        | Unsigned divide AX by r/m8, result in AL=Quotient, AH=Remainder.             |
+| F7 /6         | DIV r/m16 | M     | Valid       | Valid       | Unsigned divide DX:AX by r/m16, result in AX=Quotient, DX=Remainder.         |
+| F7 /6         | DIV r/m32 | M     | Valid       | Valid       | Unsigned divide EDX:EAX by r/m32, result in EAX=Quotient, EDX=Remainder.     |
+| REX.W + F7 /6 | DIV r/m64 | M     | Valid       | N.E.        | Unsigned divide RDX:RAX by r/m64, result in RAX=Quotient, RDX=Remainder.     |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+Non-integral results are truncated (chopped) towards 0. The remainder is always less than the divisor in magnitude. Overflow is indicated with
+the #DE (divide error) exception rather than with the CF flag.
+
+In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15).
+Use of the REX.W prefix promotes operation to 64 bits. In 64-bit mode when REX.W is applied, the instruction divides the unsigned value in
+RDX:RAX by the source operand and stores the quotient in RAX, the remainder in RDX.
diff --git a/xanual/enter.md b/xanual/enter.md
new file mode 100755 (executable)
index 0000000..6b7fd8b
--- /dev/null
@@ -0,0 +1,46 @@
+# ENTER — Make Stack Frame for Procedure Parameters
+
+## Description
+
+Creates a stack frame (comprising of space for dynamic storage and 1-32 frame pointer storage) for a procedure. The first operand (imm16)
+specifies the size of the dynamic storage in the stack frame (that is, the number of bytes of dynamically allocated on the stack for the
+procedure). The second operand (imm8) gives the lexical nesting level (0 to 31) of the procedure. The nesting level (imm8 mod 32) and the
+OperandSize attribute determine the size in bytes of the storage space for frame pointers.
+
+## Instruction
+
+| Opcode   | Assembly          | Op/En | Modern Mode | Legacy Mode | Description                                                               |
+|----------|-------------------|-------|-------------|-------------|---------------------------------------------------------------------------|
+| C8 iw 00 | ENTER imm16, 0    | II    | Valid       | Valid       | Create a stack frame for a procedure.                                     |
+| C8 iw 01 | ENTER imm16,1     | II    | Valid       | Valid       | Create a stack frame with a nested pointer for a procedure.               |
+| C8 iw ib | ENTER imm16, imm8 | II    | Valid       | Valid       | Create a stack frame with nested pointers for a procedure.                |
+
+## Information
+
+The nesting level determines the number of frame pointers that are copied into the "display area" of the new stack frame from the preceding
+frame. The default size of the frame pointer is the StackAddrSize attribute, but can be overridden using the 66H prefix. Thus, the OperandSize
+attribute determines the size of each frame pointer that will be copied into the stack frame and the data being transferred from SP/ESP/RSP
+register into the BP/EBP/RBP register.
+
+The ENTER and companion LEAVE instructions are provided to support block structured languages. The ENTER instruction (when used) is typically
+the first instruction in a procedure and is used to set up a new stack frame for a procedure. The LEAVE instruction is then used at the end of
+the procedure (just before the RET instruction) to release the stack frame.
+
+If the nesting level is 0, the processor pushes the frame pointer from the BP/EBP/RBP register onto the stack, copies the current stack pointer
+from the SP/ESP/RSP register into the BP/EBP/RBP register, and loads the SP/ESP/RSP register with the current stack-pointer value minus the
+value in the size operand. For nesting levels of 1 or greater, the processor pushes additional frame pointers on the stack before adjusting the
+stack pointer. These additional frame pointers provide the called procedure with access points to other nested frames on the stack.
+
+The ENTER instruction causes a page fault whenever a write using the final value of the stack pointer (within the current stack segment) would
+do so.
+
+In 64-bit mode, default operation size is 64 bits; 32-bit operation size cannot be encoded. Use of 66H prefix changes frame pointer operand
+size to 16 bits.
+
+When the 66H prefix is used and causing the OperandSize attribute to be less than the StackAddrSize, software is responsible for the following:
+
+• The companion LEAVE instruction must also use the 66H prefix.
+
+• The value in the RBP/EBP register prior to executing "66H ENTER" must be within the same 16KByte region of the current stack pointer
+(RSP/ESP), such that the value of RBP/EBP after "66H ENTER" remains a valid address in the stack. This ensures "66H LEAVE" can restore 16-bits
+of data from the stack.
diff --git a/xanual/idiv.md b/xanual/idiv.md
new file mode 100755 (executable)
index 0000000..75ff099
--- /dev/null
@@ -0,0 +1,28 @@
+# IDIV - Signed Divide
+
+## Description
+
+Divides the (signed) value in the AX, DX:AX, or EDX:EAX (dividend) by the source operand (divisor) and stores the result in the AX (AH:AL),
+DX:AX, or EDX:EAX registers. The source operand can be a general-purpose register or a memory location. The action of this instruction depends
+on the operand size (dividend/divisor).
+
+## Instruction
+
+| Opcode        | Assembly   | Op/En | Modern Mode | Legacy Mode | Description                                                                 |
+|---------------|------------|-------|-------------|-------------|-----------------------------------------------------------------------------|
+| F6 /7         | IDIV r/m8  | M     | Valid       | Valid       | Signed divide AX by r/m8, result in: AL=Quotient, AH=Remainder.             |
+| REX + F6 /7   | IDIV r/m8* | M     | Valid       | N.E.        | Signed divide AX by r/m8, result in AL=Quotient, AH=Remainder.              |
+| F7 /7         | IDIV r/m16 | M     | Valid       | Valid       | Signed divide DX:AX by r/m16, result in AX=Quotient, DX=Remainder.          |
+| F7 /7         | IDIV r/m32 | M     | Valid       | Valid       | Signed divide EDX:EAX by r/m32, result in EAX=Quotient, EDX=Remainder.      |
+| REX.W + F7 /7 | IDIV r/m64 | M     | Valid       | N.E.        | Signed divide RDX:RAX by r/m64, result in RAX=Quotient, RDX=Remainder.      |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+Non-integral results are truncated (chopped) towards 0. The remainder is always less than the divisor in magni- tude. Overflow is indicated
+with the #DE (divide error) exception rather than with the CF flag.
+
+In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15).
+Use of the REX.W prefix promotes operation to 64 bits. In 64-bit mode when REX.W is applied, the instruction divides the signed value in
+RDX:RAX by the source operand. RAX contains a 64-bit quotient; RDX contains a 64-bit remainder.
diff --git a/xanual/imul.md b/xanual/imul.md
new file mode 100755 (executable)
index 0000000..1bb5c76
--- /dev/null
@@ -0,0 +1,66 @@
+# IMUL - Signed Multiply
+
+## Description
+
+Performs a signed multiplication of two operands. This instruction has three forms, depending on the number of operands. It's very different
+from its unsigned version, which is similar to signed and unsigned division.
+
+## Instruction
+
+| Opcode           | Assembly               | Op/En | Modern Mode | Legacy Mode | Description                                                  |
+|------------------|------------------------|-------|-------------|-------------|--------------------------------------------------------------|
+| F6 /5            | IMUL r/m8*             | M     | Valid       | Valid       | AX=AL*r/m byte.                                              |
+| F7 /5            | IMUL r/m16             | M     | Valid       | Valid       | DX:AX=AX*r/m word.                                           |
+| F7 /5            | IMUL r/m32             | M     | Valid       | Valid       | EDX:EAX=EAX*r/m32.                                           |
+| REX.W + F7 /5    | IMUL r/m64             | M     | Valid       | N.E.        | RDX:RAX=RAX*r/m64.                                           |
+| 0F AF /r         | IMUL r16, r/m16        | RM    | Valid       | Valid       | Word stores word register*r/m16.                             |
+| 0F AF /r         | IMUL r32, r/m32        | RM    | Valid       | Valid       | Doubleword stores doubleword register*r/m32.                 |
+| REX.W + 0F AF /r | IMUL r64, r/m64        | RM    | Valid       | N.E.        | Quadword stores Quadword register*r/m64.                     |
+| 6B /r ib         | IMUL r16, r/m16, imm8  | RMI   | Valid       | Valid       | Word stores r/m16*sign-extended immediate byte.              |
+| 6B /r ib         | IMUL r32, r/m32, imm8  | RMI   | Valid       | Valid       | doubleword stores r/m32*sign-extended immediate byte.        |
+| REX.W + 6B /r ib | IMUL r64, r/m64, imm8  | RMI   | Valid       | N.E.        | Quadword stores r/m64*sign-extended immediate byte.          |
+| 69 /r iw         | IMUL r16, r/m16, imm16 | RMI   | Valid       | Valid       | Word stores r/m16*immediate word.                            |
+| 69 /r id         | IMUL r32, r/m32, imm32 | RMI   | Valid       | Valid       | Doubleword stores r/m32*immediate doubleword.                |
+| REX.W + 69 /r id | IMUL r64, r/m64, imm32 | RMI   | Valid       | N.E.        | Quadword stores r/m64*immediate doubleword.                  |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+- One-operand form — This form is identical to that used by the MUL instruction. Here, the source operand (in a general-purpose register or
+memory location) is multiplied by the value in the AL, AX, EAX, or RAX register (depending on the operand size) and the product (twice the size
+of the input operand) is stored in the AX, DX:AX, EDX:EAX, or RDX:RAX registers, respectively.
+
+- Two-operand form — With this form the destination operand (the first operand) is multiplied by the source operand (second operand). The
+destination operand is a general-purpose register and the source operand is an immediate value, a general-purpose register, or a memory
+location. The intermediate product (twice the size of the input operand) is truncated and stored in the destination operand location.
+
+- Three-operand form — This form requires a destination operand (the first operand) and two source operands (the second and the third
+operands). Here, the first source operand (which can be a general-purpose register or a memory location) is multiplied by the second source
+operand (an immediate value). The intermediate product (twice the size of the first source operand) is truncated and stored in the destination
+operand (a general-purpose register).
+
+When an immediate value is used as an operand, it is sign-extended to the length of the destination operand format.
+
+The CF and OF flags are set when the signed integer value of the intermediate product differs from the sign extended operand-size-truncated
+product, otherwise the CF and OF flags are cleared.
+
+The three forms of the IMUL instruction are similar in that the length of the product is calculated to twice the length of the operands. With
+the one-operand form, the product is stored exactly in the destination. With the two- and three- operand forms, however, the result is
+truncated to the length of the destination before it is stored in the destination register. Because of this truncation, the CF or OF flag
+should be tested to ensure that no significant bits are lost.
+
+The two- and three-operand forms may also be used with unsigned operands because the lower half of the product is the same regardless if the
+operands are signed or unsigned. The CF and OF flags, however, cannot be used to determine if the upper half of the result is non-zero.
+
+In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15).
+Use of the REX.W prefix promotes operation to 64 bits. Use of REX.W modifies the three forms of the instruction as follows.
+
+- One-operand form —The source operand (in a 64-bit general-purpose register or memory location) is multiplied by the value in the RAX register
+and the product is stored in the RDX:RAX registers.
+
+- Two-operand form — The source operand is promoted to 64 bits if it is a register or a memory location. The destination operand is promoted to
+64 bits.
+
+- Three-operand form — The first source operand (either a register or a memory location) and destination operand are promoted to 64 bits. If
+the source operand is an immediate, it is sign extended to 64 bits.
diff --git a/xanual/inc.md b/xanual/inc.md
new file mode 100755 (executable)
index 0000000..9207cd5
--- /dev/null
@@ -0,0 +1,31 @@
+# INC — Increment by 1
+
+## Description
+
+Adds 1 to the destination operand, while preserving the state of the CF flag. The destination operand can be a register or a memory location.
+This instruction allows a loop counter to be updated without disturbing the CF flag. Use a ADD instruction with an immediate operand of 1 to
+perform an increment operation that does updates the CF flag.
+
+## Instruction
+
+| Opcode        | Assembly  | Op/En | Modern Mode | Legacy Mode | Description                                                                  |
+|---------------|-----------|-------|-------------|-------------|------------------------------------------------------------------------------|
+| FE /0         | INC r/m8  | M     | Valid       | Valid       | Increment r/m byte by 1.                                                     |
+| REX + FE /0   | INC r/m8* | M     | Valid       | N.E.        | Increment r/m byte by 1.                                                     |
+| FF /0         | INC r/m16 | M     | Valid       | Valid       | Increment r/m word by 1.                                                     |
+| FF /0         | INC r/m32 | M     | Valid       | Valid       | Increment r/m doubleword by 1.                                               |
+| REX.W + FF /0 | INC r/m64 | M     | Valid       | N.E.        | Increment r/m quadword by 1.                                                 |
+| 40+ rw**      | INC r16   | O     | N.E.        | Valid       | Increment word register by 1.                                                |
+| 40+ rd        | INC r32   | O     | N.E.        | Valid       | Increment doubleword register by 1.                                          |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+- 40H through 47H are REX prefixes in 64-bit mode.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
+
+In 64-bit mode, INC r16 and INC r32 are not encodable (because opcodes 40H through 47H are REX prefixes). Otherwise, the instruction’s 64-bit
+mode default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix
+promotes operation to 64 bits.
diff --git a/xanual/jcc.md b/xanual/jcc.md
new file mode 100755 (executable)
index 0000000..afc0e47
--- /dev/null
@@ -0,0 +1,147 @@
+# Jcc — Jump if Condition Is Met
+
+## Description
+
+Checks the state of one or more of the status flags in the EFLAGS register (CF, OF, PF, SF, and ZF) and, if the flags are in the specified
+state (condition), performs a jump to the target instruction specified by the destination operand. A condition code (cc) is associated with
+each instruction to indicate the condition being tested for. If the condition is not satisfied, the jump is not performed and execution
+continues with the instruction following the Jcc instruction.
+
+## Instruction
+
+| Opcode   | Assembly    | Op/En | Modern Mode | Legacy Mode | Description                                                                     |
+|----------|-------------|-------|-------------|-------------|---------------------------------------------------------------------------------|
+| 77 cb    | JA rel8     | D     | Valid       | Valid       | Jump short if above (CF=0 and ZF=0).                                            |
+| 73 cb    | JAE rel8    | D     | Valid       | Valid       | Jump short if above or equal (CF=0).                                            |
+| 72 cb    | JB rel8     | D     | Valid       | Valid       | Jump short if below (CF=1).                                                     |
+| 76 cb    | JBE rel8    | D     | Valid       | Valid       | Jump short if below or equal (CF=1 or ZF=1).                                    |
+| 72 cb    | JC rel8     | D     | Valid       | Valid       | Jump short if carry (CF=1).                                                     |
+| E3 cb    | JCXZ rel8   | D     | N.E.        | Valid       | Jump short if CX register is 0.                                                 |
+| E3 cb    | JECXZ rel8  | D     | Valid       | Valid       | Jump short if ECX register is 0.                                                |
+| E3 cb    | JRCXZ rel8  | D     | Valid       | N.E.        | Jump short if RCX register is 0.                                                |
+| 74 cb    | JE rel8     | D     | Valid       | Valid       | Jump short if equal (ZF=1).                                                     |
+| 7F cb    | JG rel8     | D     | Valid       | Valid       | Jump short if greater (ZF=0 and SF=OF).                                         |
+| 7D cb    | JGE rel8    | D     | Valid       | Valid       | Jump short if greater or equal (SF=OF).                                         |
+| 7C cb    | JL rel8     | D     | Valid       | Valid       | Jump short if less (SF≠ OF).                                                    |
+| 7E cb    | JLE rel8    | D     | Valid       | Valid       | Jump short if less or equal (ZF=1 or SF≠ OF).                                   |
+| 76 cb    | JNA rel8    | D     | Valid       | Valid       | Jump short if not above (CF=1 or ZF=1).                                         |
+| 72 cb    | JNAE rel8   | D     | Valid       | Valid       | Jump short if not above or equal (CF=1).                                        |
+| 73 cb    | JNB rel8    | D     | Valid       | Valid       | Jump short if not below (CF=0).                                                 |
+| 77 cb    | JNBE rel8   | D     | Valid       | Valid       | Jump short if not below or equal (CF=0 and ZF=0).                               |
+| 73 cb    | JNC rel8    | D     | Valid       | Valid       | Jump short if not carry (CF=0).                                                 |
+| 75 cb    | JNE rel8    | D     | Valid       | Valid       | Jump short if not equal (ZF=0).                                                 |
+| 7E cb    | JNG rel8    | D     | Valid       | Valid       | Jump short if not greater (ZF=1 or SF≠ OF).                                     |
+| 7C cb    | JNGE rel8   | D     | Valid       | Valid       | Jump short if not greater or equal (SF≠ OF).                                    |
+| 7D cb    | JNL rel8    | D     | Valid       | Valid       | Jump short if not less (SF=OF).                                                 |
+| 7F cb    | JNLE rel8   | D     | Valid       | Valid       | Jump short if not less or equal (ZF=0 and SF=OF).                               |
+| 71 cb    | JNO rel8    | D     | Valid       | Valid       | Jump short if not overflow (OF=0).                                              |
+| 7B cb    | JNP rel8    | D     | Valid       | Valid       | Jump short if not parity (PF=0).                                                |
+| 79 cb    | JNS rel8    | D     | Valid       | Valid       | Jump short if not sign (SF=0).                                                  |
+| 75 cb    | JNZ rel8    | D     | Valid       | Valid       | Jump short if not zero (ZF=0).                                                  |
+| 70 cb    | JO rel8     | D     | Valid       | Valid       | Jump short if overflow (OF=1).                                                  |
+| 7A cb    | JP rel8     | D     | Valid       | Valid       | Jump short if parity (PF=1).                                                    |
+| 7A cb    | JPE rel8    | D     | Valid       | Valid       | Jump short if parity even (PF=1).                                               |
+| 7B cb    | JPO rel8    | D     | Valid       | Valid       | Jump short if parity odd (PF=0).                                                |
+| 78 cb    | JS rel8     | D     | Valid       | Valid       | Jump short if sign (SF=1).                                                      |
+| 74 cb    | JZ rel8     | D     | Valid       | Valid       | Jump short if zero (ZF = 1).                                                    |
+| 0F 87 cw | JA rel16    | D     | N.S.        | Valid       | Jump near if above (CF=0 and ZF=0).                                             |
+| 0F 87 cd | JA rel32    | D     | Valid       | Valid       | Jump near if above (CF=0 and ZF=0).                                             |
+| 0F 83 cw | JAE rel16   | D     | N.S.        | Valid       | Jump near if above or equal (CF=0).                                             |
+| 0F 83 cd | JAE rel32   | D     | Valid       | Valid       | Jump near if above or equal (CF=0).                                             |
+| 0F 82 cw | JB rel16    | D     | N.S.        | Valid       | Jump near if below (CF=1).                                                      |
+| 0F 82 cd | JB rel32    | D     | Valid       | Valid       | Jump near if below (CF=1).                                                      |
+| 0F 86 cw | JBE rel16   | D     | N.S.        | Valid       | Jump near if below or equal (CF=1 or ZF=1).                                     |
+| 0F 86 cd | JBE rel32   | D     | Valid       | Valid       | Jump near if below or equal (CF=1 or ZF=1).                                     |
+| 0F 82 cw | JC rel16    | D     | N.S.        | Valid       | Jump near if carry (CF=1).                                                      |
+| 0F 82 cd | JC rel32    | D     | Valid       | Valid       | Jump near if carry (CF=1).                                                      |
+| 0F 84 cw | JE rel16    | D     | N.S.        | Valid       | Jump near if equal (ZF=1).                                                      |
+| 0F 84 cd | JE rel32    | D     | Valid       | Valid       | Jump near if equal (ZF=1).                                                      |
+| 0F 84 cw | JZ rel16    | D     | N.S.        | Valid       | Jump near if 0 (ZF=1).                                                          |
+| 0F 84 cd | JZ rel32    | D     | Valid       | Valid       | Jump near if 0 (ZF=1).                                                          |
+| 0F 8F cw | JG rel16    | D     | N.S.        | Valid       | Jump near if greater (ZF=0 and SF=OF).                                          |
+| 0F 8F cd | JG rel32    | D     | Valid       | Valid       | Jump near if greater (ZF=0 and SF=OF).                                          |
+| 0F 8D cw | JGE rel16   | D     | N.S.        | Valid       | Jump near if greater or equal (SF=OF).                                          |
+| 0F 8D cd | JGE rel32   | D     | Valid       | Valid       | Jump near if greater or equal (SF=OF).                                          |
+| 0F 8C cw | JL rel16    | D     | N.S.        | Valid       | Jump near if less (SF≠ OF).                                                     |
+| 0F 8C cd | JL rel32    | D     | Valid       | Valid       | Jump near if less (SF≠ OF).                                                     |
+| 0F 8E cw | JLE rel16   | D     | N.S.        | Valid       | Jump near if less or equal (ZF=1 or SF≠ OF).                                    |
+| 0F 8E cd | JLE rel32   | D     | Valid       | Valid       | Jump near if less or equal (ZF=1 or SF≠ OF).                                    |
+| 0F 86 cw | JNA rel16   | D     | N.S.        | Valid       | Jump near if not above (CF=1 or ZF=1).                                          |
+| 0F 86 cd | JNA rel32   | D     | Valid       | Valid       | Jump near if not above (CF=1 or ZF=1).                                          |
+| 0F 82 cw | JNAE rel16  | D     | N.S.        | Valid       | Jump near if not above or equal (CF=1).                                         |
+| 0F 82 cd | JNAE rel32  | D     | Valid       | Valid       | Jump near if not above or equal (CF=1).                                         |
+| 0F 83 cw | JNB rel16   | D     | N.S.        | Valid       | Jump near if not below (CF=0).                                                  |
+| 0F 83 cd | JNB rel32   | D     | Valid       | Valid       | Jump near if not below (CF=0).                                                  |
+| 0F 87 cw | JNBE rel16  | D     | N.S.        | Valid       | Jump near if not below or equal (CF=0 and ZF=0).                                |
+| 0F 87 cd | JNBE rel32  | D     | Valid       | Valid       | Jump near if not below or equal (CF=0 and ZF=0).                                |
+| 0F 83 cw | JNC rel16   | D     | N.S.        | Valid       | Jump near if not carry (CF=0).                                                  |
+| 0F 83 cd | JNC rel32   | D     | Valid       | Valid       | Jump near if not carry (CF=0).                                                  |
+| 0F 85 cw | JNE rel16   | D     | N.S.        | Valid       | Jump near if not equal (ZF=0).                                                  |
+| 0F 85 cd | JNE rel32   | D     | Valid       | Valid       | Jump near if not equal (ZF=0).                                                  |
+| 0F 8E cw | JNG rel16   | D     | N.S.        | Valid       | Jump near if not greater (ZF=1 or SF≠ OF).                                      |
+| 0F 8E cd | JNG rel32   | D     | Valid       | Valid       | Jump near if not greater (ZF=1 or SF≠ OF).                                      |
+| 0F 8C cw | JNGE rel16  | D     | N.S.        | Valid       | Jump near if not greater or equal (SF≠ OF).                                     |
+| 0F 8C cd | JNGE rel32  | D     | Valid       | Valid       | Jump near if not greater or equal (SF≠ OF).                                     |
+| 0F 8D cw | JNL rel16   | D     | N.S.        | Valid       | Jump near if not less (SF=OF).                                                  |
+| 0F 8D cd | JNL rel32   | D     | Valid       | Valid       | Jump near if not less (SF=OF).                                                  |
+| 0F 8F cw | JNLE rel16  | D     | N.S.        | Valid       | Jump near if not less or equal (ZF=0 and SF=OF).                                |
+| 0F 8F cd | JNLE rel32  | D     | Valid       | Valid       | Jump near if not less or equal (ZF=0 and SF=OF).                                |
+| 0F 81 cw | JNO rel16   | D     | N.S.        | Valid       | Jump near if not overflow (OF=0).                                               |
+| 0F 81 cd | JNO rel32   | D     | Valid       | Valid       | Jump near if not overflow (OF=0).                                               |
+| 0F 8B cw | JNP rel16   | D     | N.S.        | Valid       | Jump near if not parity (PF=0).                                                 |
+| 0F 8B cd | JNP rel32   | D     | Valid       | Valid       | Jump near if not parity (PF=0).                                                 |
+| 0F 89 cw | JNS rel16   | D     | N.S.        | Valid       | Jump near if not sign (SF=0).                                                   |
+| 0F 89 cd | JNS rel32   | D     | Valid       | Valid       | Jump near if not sign (SF=0).                                                   |
+| 0F 85 cw | JNZ rel16   | D     | N.S.        | Valid       | Jump near if not zero (ZF=0).                                                   |
+| 0F 85 cd | JNZ rel32   | D     | Valid       | Valid       | Jump near if not zero (ZF=0).                                                   |
+| 0F 80 cw | JO rel16    | D     | N.S.        | Valid       | Jump near if overflow (OF=1).                                                   |
+| 0F 80 cd | JO rel32    | D     | Valid       | Valid       | Jump near if overflow (OF=1).                                                   |
+| 0F 8A cw | JP rel16    | D     | N.S.        | Valid       | Jump near if parity (PF=1).                                                     |
+| 0F 8A cd | JP rel32    | D     | Valid       | Valid       | Jump near if parity (PF=1)                                                      |
+| 0F 8A cw | JPE rel16   | D     | N.S.        | Valid       | Jump near if parity even (PF=1).                                                |
+| 0F 8A cd | JPE rel32   | D     | Valid       | Valid       | Jump near if parity even (PF=1).                                                |
+| 0F 8B cw | JPO rel16   | D     | N.S.        | Valid       | Jump near if parity odd (PF=0).                                                 |
+| 0F 8B cd | JPO rel32   | D     | Valid       | Valid       | Jump near if parity odd (PF=0).                                                 |
+| 0F 88 cw | JS rel16    | D     | N.S.        | Valid       | Jump near if sign (SF=1).                                                       |
+| 0F 88 cd | JS rel32    | D     | Valid       | Valid       | Jump near if sign (SF=1).                                                       |
+| 0F 84 cw | JZ rel16    | D     | N.S.        | Valid       | Jump near if 0 (ZF=1).                                                          |
+| 0F 84 cd | JZ rel32    | D     | Valid       | Valid       | Jump near if 0 (ZF=1).                                                          |
+
+## Information
+
+The target instruction is specified with a relative offset (a signed offset relative to the current value of the instruction pointer in the EIP
+register). A relative offset (rel8, rel16, or rel32) is generally specified as a label in assembly code, but at the machine code level, it is
+encoded as a signed, 8-bit or 32-bit immediate value, which is added to the instruction pointer. Instruction coding is most efficient for
+offsets of –128 to +127. If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared, resulting in a maximum
+instruction pointer size of 16 bits. The conditions for each Jcc mnemonic are given in the “Description” column of the table on the preceding
+page. The terms “less” and “greater” are used for comparisons of signed integers and the terms “above” and “below” are used for unsigned
+integers.
+
+Because a particular state of the status flags can sometimes be interpreted in two ways, two mnemonics are defined for some opcodes. For
+example, the JA (jump if above) instruction and the JNBE (jump if not below or equal) instruction are alternate mnemonics for the opcode 77H.
+
+The Jcc instruction does not support far jumps (jumps to other code segments). When the target for the conditional jump is in a different
+segment, use the opposite condition from the condition being tested for the Jcc instruction, and then access the target with an unconditional
+far jump (JMP instruction) to the other segment. For example, the following conditional far jump is illegal:
+
+```
+JZ FARLABEL;
+```
+
+To accomplish this far jump, use the following two instructions:
+
+```
+JNZ BEYOND;
+JMP FARLABEL;
+BEYOND:
+```
+
+The JRCXZ, JECXZ and JCXZ instructions differ from other Jcc instructions because they do not check status flags. Instead, they check RCX, ECX
+or CX for 0. The register checked is determined by the address-size attribute. These instructions are useful when used at the beginning of a
+loop that terminates with a conditional loop instruction (such as LOOPNE). They can be used to prevent an instruction sequence from entering a
+loop when RCX, ECX or CX is 0. This would cause the loop to execute 264, 2 32 or 64K times (not zero times).
+
+All conditional jumps are converted to code fetches of one or two cache lines, regardless of jump address or cache-ability.
+
+In 64-bit mode, operand size is fixed at 64 bits. JMP Short is RIP = RIP + 8-bit offset sign extended to 64 bits. JMP Near is RIP = RIP +
+32-bit offset sign extended to 64-bits.
diff --git a/xanual/jmp.md b/xanual/jmp.md
new file mode 100755 (executable)
index 0000000..65c5967
--- /dev/null
@@ -0,0 +1,103 @@
+# JMP - Jump
+
+## Description
+
+Transfers program control to a different point in the instruction stream without recording return information. The destination (target) operand
+specifies the address of the instruction being jumped to. This operand can be an immediate value, a general-purpose register, or a memory
+location.
+
+## Instruction
+
+| Opcode        | Assembly     | Op/En | Modern Mode | Legacy Mode | Description                                                               |
+|---------------|--------------|-------|-------------|-------------|---------------------------------------------------------------------------|
+| EB cb         | JMP rel8     | D     | Valid       | Valid       | Jump short, RIP = RIP + 8-bit displacement sign extended.                 |
+| E9 cw         | JMP rel16    | D     | N.S.        | Valid       | Jump near, relative, displacement relative to next instruction.           |
+| E9 cd         | JMP rel32    | D     | Valid       | Valid       | Jump near, relative, RIP = RIP + 32-bit displacement sign extended        |
+| FF /4         | JMP r/m16    | M     | N.S.        | Valid       | Jump near, absolute indirect, address = zero- extended r/m16.             |
+| FF /4         | JMP r/m32    | M     | N.S.        | Valid       | Jump near, absolute indirect, address given in r/m32.                     |
+| FF /4         | JMP r/m64    | M     | Valid       | N.E.        | Jump near, absolute indirect, RIP = 64-bit from register or memory.       |
+| EA cd         | JMP ptr16:16 | D     | Invalid     | Valid       | Jump far, absolute, address given in operand.                             |
+| EA cp         | JMP ptr16:32 | D     | Invalid     | Valid       | Jump far, absolute, address given in operand.                             |
+| FF /5         | JMP m16:16   | D     | Valid       | Valid       | Jump far, absolute indirect, address given in m16:16.                     |
+| FF /5         | JMP m16:32   | D     | Valid       | Valid       | Jump far, absolute indirect, address given in m16:32.                     |
+| REX.W + FF /5 | JMP m16:64   | D     | Valid       | N.E.        | Jump far, absolute indirect, address given in m16:64.                     |
+
+## Information
+
+This instruction can be used to execute four different types of jumps:
+
+- Near jump — A jump to an instruction within the current code segment (the segment currently pointed to by the CS register), sometimes referred
+to as an intrasegment jump.
+
+- Short jump — A near jump where the jump range is limited to –128 to +127 from the current EIP value.
+
+- Far jump — A jump to an instruction located in a different segment than the current code segment but at the same privilege level, sometimes
+referred to as an intersegment jump.
+
+- Task switch — A jump to an instruction located in a different task.
+
+A task switch can only be executed in protected mode.
+
+Near and Short Jumps. When executing a near jump, the processor jumps to the address (within the current code segment) that is specified with
+the target operand. The target operand specifies either an absolute offset (that is an offset from the base of the code segment) or a relative
+offset (a signed displacement relative to the current value of the instruction pointer in the EIP register). A near jump to a relative offset
+of 8-bits (rel8) is referred to as a short jump. The CS register is not changed on near and short jumps.
+
+An absolute offset is specified indirectly in a general-purpose register or a memory location (r/m16 or r/m32). The operand-size attribute
+determines the size of the target operand (16 or 32 bits). Absolute offsets are loaded directly into the EIP register. If the operand-size
+attribute is 16, the upper two bytes of the EIP register are cleared, resulting in a maximum instruction pointer size of 16 bits.
+
+A relative offset (rel8, rel16, or rel32) is generally specified as a label in assembly code, but at the machine code level, it is encoded as a
+signed 8-, 16-, or 32-bit immediate value. This value is added to the value in the EIP register. (Here, the EIP register contains the address
+of the instruction following the JMP instruction). When using relative offsets, the opcode (for short vs. near jumps) and the operand-size
+attribute (for near relative jumps) determines the size of the target operand (8, 16, or 32 bits).
+
+Far Jumps in Real-Address or Virtual-8086 Mode. When executing a far jump in real-address or virtual-8086 mode, the processor jumps to the code
+segment and offset specified with the target operand. Here the target operand specifies an absolute far address either directly with a pointer
+(ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). With the pointer method, the segment and address of the called
+procedure is encoded in the instruction, using a 4-byte (16-bit operand size) or 6-byte (32-bit operand size) far address immediate. With the
+indirect method, the target operand specifies a memory location that contains a 4-byte (16-bit operand size) or 6-byte (32-bit operand size)
+far address. The far address is loaded directly into the CS and EIP registers. If the operand-size attribute is 16, the upper two bytes of the
+EIP register are cleared.
+
+Far Jumps in Protected Mode. When the processor is operating in protected mode, the JMP instruction can be used to perform the following three
+types of far jumps:
+
+- A far jump to a conforming or non-conforming code segment.
+- A far jump through a call gate.
+- A task switch.
+
+The JMP instruction cannot be used to perform inter-privilege-level far jumps.
+
+In protected mode, the processor always uses the segment selector part of the far address to access the corresponding descriptor in the GDT or
+LDT. The descriptor type (code segment, call gate, task gate, or TSS) and access rights determine the type of jump to be performed.
+
+If the selected descriptor is for a code segment, a far jump to a code segment at the same privilege level is performed. (If the selected code
+segment is at a different privilege level and the code segment is non-conforming, a general-protection exception is generated.) A far jump to
+the same privilege level in protected mode is very similar to one carried out in real-address or virtual-8086 mode. The target operand
+specifies an absolute far address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or
+m16:32). The operand-size attribute determines the size of the offset (16 or 32 bits) in the far address. The new code segment selector and its
+descriptor are loaded into CS register, and the offset from the instruction is loaded into the EIP register. Note that a call gate (described
+in the next paragraph) can also be used to perform far call to a code segment at the same privilege level. Using this mechanism provides an
+extra level of indirection and is the preferred method of making jumps between 16-bit and 32-bit code segments.
+
+When executing a far jump through a call gate, the segment selector specified by the target operand identifies the call gate. The offset part
+of the target operand is ignored. The processor then jumps to the code segment specified in the call gate descriptor and begins executing the
+instruction at the offset specified in the call gate. No stack switch occurs. Here again, the target operand can specify the far address of the
+call gate either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32).
+
+Executing a task switch with the JMP instruction is somewhat similar to executing a jump through a call gate. Here the target operand specifies
+the segment selector of the task gate for the task being switched to (and the offset part of the target operand is ignored). The task gate in
+turn points to the TSS for the task, which contains the segment selectors for the task’s code and stack segments. The TSS also contains the EIP
+value for the next instruction that was to be executed before the task was suspended. This instruction pointer value is loaded into the EIP
+register so that the task begins executing again at this next instruction.
+
+The JMP instruction can also specify the segment selector of the TSS directly, which eliminates the indirection of the task gate.
+
+Note that when you execute at task switch with a JMP instruction, the nested task flag (NT) is not set in the EFLAGS register and the new TSS’s
+previous task link field is not loaded with the old task’s TSS selector. A return to the previous task can thus not be carried out by executing
+the IRET instruction. Switching tasks with the JMP instruction differs in this regard from the CALL instruction which does set the NT flag and
+save the previous task link information, allowing a return to the calling task with an IRET instruction.
+
+In 64-Bit Mode — The instruction’s operation size is fixed at 64 bits. If a selector points to a gate, then RIP equals the 64-bit displacement
+taken from gate; else RIP equals the zero-extended offset from the far pointer referenced in the instruction.
diff --git a/xanual/leave.md b/xanual/leave.md
new file mode 100755 (executable)
index 0000000..9414082
--- /dev/null
@@ -0,0 +1,20 @@
+# LEAVE — High Level Procedure Exit
+
+## Description
+
+Releases the stack frame set up by an earlier ENTER instruction. The LEAVE instruction copies the frame pointer (in the EBP register) into the
+stack pointer register (ESP), which releases the stack space allocated to the stack frame. The old frame pointer (the frame pointer for the
+calling procedure that was saved by the ENTER instruction) is then popped from the stack into the EBP register, restoring the calling
+procedure's stack frame.
+
+## Instruction
+
+| Opcode | Assembly | Op/En | Modern Mode | Legacy Mode | Description                                                                          |
+|--------|----------|-------|-------------|-------------|--------------------------------------------------------------------------------------|
+| C9     | LEAVE    | NP    | Valid       | Valid       | Set SP to BP, then pop BP.                                                           |
+| C9     | LEAVE    | NP    | N.E.        | Valid       | Set ESP to EBP, then pop EBP.                                                        |
+| C9     | LEAVE    | NP    | Valid       | N.E.        | Set RSP to RBP, then pop RBP.                                                        |
+
+## Information
+
+A RET instruction is commonly executed following a LEAVE instruction to return program control to the calling procedure.
diff --git a/xanual/mov.md b/xanual/mov.md
new file mode 100755 (executable)
index 0000000..2e91c6c
--- /dev/null
@@ -0,0 +1,78 @@
+# MOV — Move
+
+## Description
+
+Copies the second operand (source operand) to the first operand (destination operand). The source operand can be an immediate value,
+general-purpose register, segment register, or memory location; the destination register can be a general-purpose register, segment register,
+or memory location. Both operands must be the same size, which can be a byte, a word, a doubleword, or a quadword.
+
+## Instruction
+
+| Opcode            | Assembly          | Op/En | Modern Mode | Legacy Mode | Description                                                      |
+|-------------------|-------------------|-------|-------------|-------------|------------------------------------------------------------------|
+| 88 /r             | MOV r/m8,r8       | MR    | Valid       | Valid       | Move r8 to r/m8.                                                 |
+| REX + 88 /r       | MOV r/m8***,r8*** | MR    | Valid       | N.E.        | Move r8 to r/m8.                                                 |
+| 89 /r             | MOV r/m16,r16     | MR    | Valid       | Valid       | Move r16 to r/m16.                                               |
+| 89 /r             | MOV r/m32,r32     | MR    | Valid       | Valid       | Move r32 to r/m32.                                               |
+| REX.W + 89 /r     | MOV r/m64,r64     | MR    | Valid       | N.E.        | Move r64 to r/m64.                                               |
+| 8A /r             | MOV r8,r/m8       | RM    | Valid       | Valid       | Move r/m8 to r8.                                                 |
+| REX + 8A /r       | MOV r8***,r/m8*** | RM    | Valid       | N.E.        | Move r/m8 to r8.                                                 |
+| 8B /r             | MOV r16,r/m16     | RM    | Valid       | Valid       | Move r/m16 to r16.                                               |
+| 8B /r             | MOV r32,r/m32     | RM    | Valid       | Valid       | Move r/m32 to r32.                                               |
+| REX.W + 8B /r     | MOV r64,r/m64     | RM    | Valid       | N.E.        | Move r/m64 to r64.                                               |
+| 8C /r             | MOV r/m16,Sreg**  | MR    | Valid       | Valid       | Move segment register to r/m16.                                  |
+| REX.W + 8C /r     | MOV r/m64,Sreg**  | MR    | Valid       | Valid       | Move zero extended 16-bit segment register to r/m64.             |
+| 8E /r             | MOV Sreg,r/m16**  | RM    | Valid       | Valid       | Move r/m16 to segment register.                                  |
+| REX.W + 8E /r     | MOV Sreg,r/m64**  | RM    | Valid       | Valid       | Move lower 16 bits of r/m64 to segment register.                 |
+| A0                | MOV AL,moffs8*    | FD    | Valid       | Valid       | Move byte at (seg:offset) to AL.                                 |
+| REX.W + A0        | MOV AL,moffs8*    | FD    | Valid       | N.E.        | Move byte at (offset) to AL.                                     |
+| A1                | MOV AX,moffs16*   | FD    | Valid       | Valid       | Move word at (seg:offset) to AX.                                 |
+| A1                | MOV EAX,moffs32*  | FD    | Valid       | Valid       | Move doubleword at (seg:offset) to EAX.                          |
+| REX.W + A1        | MOV RAX,moffs64*  | FD    | Valid       | N.E.        | Move quadword at (offset) to RAX.                                |
+| A2                | MOV moffs8,AL     | TD    | Valid       | Valid       | Move AL to (seg:offset).                                         |
+| REX.W + A2        | MOV moffs8***,AL  | TD    | Valid       | N.E.        | Move AL to (offset).                                             |
+| A3                | MOV moffs16*,AX   | TD    | Valid       | Valid       | Move AX to (seg:offset).                                         |
+| A3                | MOV moffs32*,EAX  | TD    | Valid       | Valid       | Move EAX to (seg:offset).                                        |
+| REX.W + A3        | MOV moffs64*,RAX  | TD    | Valid       | N.E.        | Move RAX to (offset).                                            |
+| B0+ rb ib         | MOV r8, imm8      | OI    | Valid       | Valid       | Move imm8 to r8.                                                 |
+| REX + B0+ rb ib   | MOV r8***, imm8   | OI    | Valid       | N.E.        | Move imm8 to r8.                                                 |
+| B8+ rw iw         | MOV r16, imm16    | OI    | Valid       | Valid       | Move imm16 to r16.                                               |
+| B8+ rd id         | MOV r32, imm32    | OI    | Valid       | Valid       | Move imm32 to r32.                                               |
+| REX.W + B8+ rd io | MOV r64, imm64    | OI    | Valid       | N.E.        | Move imm64 to r64.                                               |
+| C6 /0 ib          | MOV r/m8, imm8    | MI    | Valid       | Valid       | Move imm8 to r/m8.                                               |
+| REX + C6 /0 ib    | MOV r/m8***, imm8 | MI    | Valid       | N.E.        | Move imm8 to r/m8.                                               |
+| C7 /0 iw          | MOV r/m16, imm16  | MI    | Valid       | Valid       | Move imm16 to r/m16.                                             |
+| C7 /0 id          | MOV r/m32, imm32  | MI    | Valid       | Valid       | Move imm32 to r/m32.                                             |
+| REX.W + C7 /0 id  | MOV r/m64, imm32  | MI    | Valid       | N.E.        | Move imm32 sign extended to 64-bits to r/m64.                    |
+
+- The moffs8, moffs16, moffs32 and moffs64 operands specify a simple offset relative to the segment base, where 8, 16, 32 and 64 refer to the
+size of the data. The address-size attribute of the instruction determines the size of the offset, either 16, 32 or 64 bits.
+
+- In 32-bit mode, the assembler may insert the 16-bit operand-size prefix with this instruction.
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+The MOV instruction cannot be used to load the CS register. Attempting to do so results in an invalid opcode exception (#UD). To load the CS
+register, use the far JMP, CALL, or RET instruction.
+
+If the destination operand is a segment register (DS, ES, FS, GS, or SS), the source operand must be a valid segment selector. In protected
+mode, moving a segment selector into a segment register automatically causes the segment descriptor information associated with that segment
+selector to be loaded into the hidden (shadow) part of the segment register. While loading this information, the segment selector and segment
+descriptor information is validated (see the "Operation" algorithm below). The segment descriptor data is obtained from the GDT or LDT entry
+for the specified segment selector.
+
+A NULL segment selector (values 0000-0003) can be loaded into the DS, ES, FS, and GS registers without causing a protection exception. However,
+any subsequent attempt to reference a segment whose corresponding segment register is loaded with a NULL value causes a general protection
+exception (#GP) and no memory reference occurs. Loading the SS register with a MOV instruction inhibits all interrupts until after the
+execution of the next instruc- tion. This operation allows a stack pointer to be loaded into the ESP register with the next instruction (MOV
+ESP, stack-pointer value) before an interrupt occurs. Be aware that the LSS instruction offers a more efficient method of loading the SS and
+ESP registers.
+
+When executing MOV Reg, Sreg, the processor copies the content of Sreg to the 16 least significant bits of the general-purpose register. The
+upper bits of the destination register are zero for most IA-32 processors (Pentium Pro processors and later) and all Intel 64 processors, with
+the exception that bits 31:16 are undefined for Intel Quark X1000 processors, Pentium and earlier processors.
+
+In 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15).
+Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.
diff --git a/xanual/mul.md b/xanual/mul.md
new file mode 100755 (executable)
index 0000000..10ae89e
--- /dev/null
@@ -0,0 +1,28 @@
+ MUL - Unsigned Multiply
+
+## Description
+
+Performs an unsigned multiplication of the first operand (destination operand) and the second operand (source operand) and stores the result in
+the destination operand. The destination operand is an implied operand located in register AL, AX or EAX (depending on the size of the operand).
+The source operand is located in a general-purpose register or a memory location.
+
+## Instruction
+
+| Opcode        | Assembly  | Op/En | Modern Mode | Legacy Mode | Description                                                                  |
+|---------------|-----------|-------|-------------|-------------|------------------------------------------------------------------------------|
+| F6 /4         | MUL r/m8  | M     | Valid       | Valid       | Unsigned multiply (AX=AL*r/m8).                                              |
+| REX + F6 /4   | MUL r/m8* | M     | Valid       | N.E.        | Unsigned multiply (AX=AL*r/m8).                                              |
+| F7 /4         | MUL r/m16 | M     | Valid       | Valid       | Unsigned multiply (DX:AX=AX*r/m16).                                          |
+| F7 /4         | MUL r/m32 | M     | Valid       | Valid       | Unsigned multiply (EDX:EAX=EAX*r/m32).                                       |
+| REX.W + F7 /4 | MUL r/m64 | M     | Valid       | N.E.        | Unsigned multiply (RDX:RAX=RAX*r/m64).                                       |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+The result is stored in register AX, register pair DX:AX, or register pair EDX:EAX (depending on the operand size), with the high-order bits of
+the product contained in register AH, DX, or EDX, respectively. If the high-order bits of the product are 0, the CF and OF flags are cleared;
+otherwise, the flags are set.
+
+In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15).
+Use of the REX.W prefix promotes operation to 64 bits.
diff --git a/xanual/neg.md b/xanual/neg.md
new file mode 100755 (executable)
index 0000000..e919a4e
--- /dev/null
@@ -0,0 +1,26 @@
+# NEG — Two's Complement Negation
+
+## Description
+
+Replaces the value of operand (the destination operand) with its two's complement. This operation is equivalent to subtracting the operand
+from 0. The destination operand is located in a general-purpose register or a memory location.
+
+## Instruction
+
+| Opcode        | Assembly   | Op/En | Modern Mode | Legacy Mode | Description                                                                 |
+|---------------|------------|-------|-------------|-------------|-----------------------------------------------------------------------------|
+| F6 /3         | NEG r/m8   | M     | Valid       | Valid       | Two's complement negate r/m8.                                               |
+| REX + F6 /3   | NEG r/m8*  | M     | Valid       | N.E.        | Two's complement negate r/m8.                                               |
+| F7 /3         | NEG r/m16  | M     | Valid       | Valid       | Two's complement negate r/m16.                                              |
+| F7 /3         | NEG r/m32  | M     | Valid       | Valid       | Two's complement negate r/m32.                                              |
+| REX.W + F7 /3 | NEG r/m64  | M     | Valid       | N.E.        | Two's complement negate r/m64.                                              |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
+
+In 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional
+registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this
+section for encoding data and limits.
diff --git a/xanual/nop.md b/xanual/nop.md
new file mode 100755 (executable)
index 0000000..aab6665
--- /dev/null
@@ -0,0 +1,40 @@
+# NOP - No Operation
+
+## Description
+
+This instruction performs no operation. It is a one-byte or multi-byte NOP that takes up space in the instruction stream but does not impact
+machine context, except for the EIP register.
+
+## Instruction
+
+| Opcode   | Assembly    | Op/En | Modern Mode | Legacy Mode | Description                                                                     |
+|----------|-------------|-------|-------------|-------------|---------------------------------------------------------------------------------|
+| 90       | NOP         | NP    | Valid       | Valid       | One byte no-operation instruction.                                              |
+| 0F 1F /0 | NOP r/m16   | M     | Valid       | Valid       | Multi-byte no-operation instruction.                                            |
+| 0F 1F /0 | NOP r/m32   | M     | Valid       | Valid       | Multi-byte no-operation instruction.                                            |
+
+## Information
+
+The multi-byte form of NOP is available on processors with model encoding:
+
+- CPUID.01H.EAX (Bytes 11:8) = 0110B or 1111B
+
+The multi-byte NOP instruction does not alter the content of a register and will not issue a memory operation. The instruction’s operation is
+the same in non-64-bit modes and 64-bit mode.
+
+## Operation
+
+The one-byte NOP instruction is an alias mnemonic for the XCHG (E)AX, (E)AX instruction. The multi-byte NOP instruction performs no operation
+on supported processors and generates undefined opcode exception on processors that do not support the multi-byte NOP instruction.
+
+The memory operand form of the instruction allows software to create a byte sequence of “no operation” as one instruction. For situations where
+multiple-byte NOPs are needed, the recommended operations (32-bit mode and 64-bit mode) are:
+
+- 2 bytes `66 NOP 66 90H`
+- 3 bytes `NOP DWORD ptr (EAX) 0F 1F 00H`
+- 4 bytes `NOP DWORD ptr (EAX + 00H) 0F 1F 40 00H`
+- 5 bytes `NOP DWORD ptr (EAX + EAX*1 + 00H) 0F 1F 44 00 00H`
+- 6 bytes `66 NOP DWORD ptr (EAX + EAX*1 + 00H) 66 0F 1F 44 00 00H`
+- 7 bytes `NOP DWORD ptr (EAX + 00000000H) 0F 1F 80 00 00 00 00H`
+- 8 bytes `NOP DWORD ptr (EAX + EAX*1 + 00000000H) 0F 1F 84 00 00 00 00 00H`
+- 9 bytes `66 NOP DWORD ptr (EAX + EAX*1 + 00000000H) 66 0F 1F 84 00 00 00 00 00H`
diff --git a/xanual/not.md b/xanual/not.md
new file mode 100755 (executable)
index 0000000..545dccc
--- /dev/null
@@ -0,0 +1,26 @@
+# NOT — One's Complement Negation
+
+## Description
+
+Performs a bitwise NOT operation (each 1 is set to 0, and each 0 is set to 1) on the destination operand and stores the result in the
+destination operand location. The destination operand can be a register or a memory location.
+
+## Instruction
+
+| Opcode        | Assembly   | Op/En | Modern Mode | Legacy Mode | Description                                                                 |
+|---------------|------------|-------|-------------|-------------|-----------------------------------------------------------------------------|
+| F6 /2         | NOT r/m8   | M     | Valid       | Valid       | Reverse each bit of r/m8.                                                   |
+| REX + F6 /2   | NOT r/m8*  | M     | Valid       | N.E.        | Reverse each bit of r/m8.                                                   |
+| F7 /2         | NOT r/m16  | M     | Valid       | Valid       | Reverse each bit of r/m16.                                                  |
+| F7 /2         | NOT r/m32  | M     | Valid       | Valid       | Reverse each bit of r/m32.                                                  |
+| REX.W + F7 /2 | NOT r/m64  | M     | Valid       | N.E.        | Reverse each bit of r/m64.                                                  |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
+
+In 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional
+registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this
+section for encoding data and limits.
diff --git a/xanual/or.md b/xanual/or.md
new file mode 100755 (executable)
index 0000000..cad76ef
--- /dev/null
@@ -0,0 +1,45 @@
+# OR — Logical Inclusive Or
+
+## Description
+
+Performs a bitwise inclusive OR operation between the destination (first) and source (second) operands and stores the result in the destination
+operand location. The source operand can be an immediate, a register, or a memory location; the destination operand can be a register or a
+memory location. However, two memory operands cannot be used in one instruction. Each bit of the result of the OR instruction is set to 0 if
+both corresponding bits of the first and second operands are 0; otherwise, each bit is set to 1.
+
+## Instruction
+
+| Opcode           | Assembly        | Op/En | Modern Mode | Legacy Mode | Description                                                         |
+|------------------|-----------------|-------|-------------|-------------|---------------------------------------------------------------------|
+| 0C ib            | OR AL, imm8     | I     | Valid       | Valid       | AL OR imm8.                                                         |
+| 0D iw            | OR AX, imm16    | I     | Valid       | Valid       | AX OR imm16.                                                        |
+| 0D id            | OR EAX, imm32   | I     | Valid       | Valid       | EAX OR imm32.                                                       |
+| REX.W + 0D id    | OR RAX, imm32   | I     | Valid       | N.E.        | RAX OR imm32 (sign-extended).                                       |
+| 80 /1 ib         | OR r/m8, imm8   | MI    | Valid       | Valid       | r/m8 OR imm8.                                                       |
+| REX + 80 /1 ib   | OR r/m8*, imm8  | MI    | Valid       | N.E.        | r/m8 OR imm8.                                                       |
+| 81 /1 iw         | OR r/m16, imm16 | MI    | Valid       | Valid       | r/m16 OR imm16.                                                     |
+| 81 /1 id         | OR r/m32, imm32 | MI    | Valid       | Valid       | r/m32 OR imm32.                                                     |
+| REX.W + 81 /1 id | OR r/m64, imm32 | MI    | Valid       | N.E.        | r/m64 OR imm32 (sign-extended).                                     |
+| 83 /1 ib         | OR r/m16, imm8  | MI    | Valid       | Valid       | r/m16 OR imm8 (sign-extended).                                      |
+| 83 /1 ib         | OR r/m32, imm8  | MI    | Valid       | Valid       | r/m32 OR imm8 (sign-extended).                                      |
+| REX.W + 83 /1 ib | OR r/m64, imm8  | MI    | Valid       | N.E.        | r/m64 OR imm8 (sign-extended).                                      |
+| 08 /r            | OR r/m8, r8     | MR    | Valid       | Valid       | r/m8 OR r8.                                                         |
+| REX + 08 /r      | OR r/m8*, r8*   | MR    | Valid       | N.E.        | r/m8 OR r8.                                                         |
+| 09 /r            | OR r/m16, r16   | MR    | Valid       | Valid       | r/m16 OR r16.                                                       |
+| 09 /r            | OR r/m32, r32   | MR    | Valid       | Valid       | r/m32 OR r32.                                                       |
+| REX.W + 09 /r    | OR r/m64, r64   | MR    | Valid       | N.E.        | r/m64 OR r64.                                                       |
+| 0A /r            | OR r8, r/m8     | RM    | Valid       | Valid       | r8 OR r/m8.                                                         |
+| REX + 0A /r      | OR r8*, r/m8*   | RM    | Valid       | N.E.        | r8 OR r/m8.                                                         |
+| 0B /r            | OR r16, r/m16   | RM    | Valid       | Valid       | r16 OR r/m16.                                                       |
+| 0B /r            | OR r32, r/m32   | RM    | Valid       | Valid       | r32 OR r/m32.                                                       |
+| REX.W + 0B /r    | OR r64, r/m64   | RM    | Valid       | N.E.        | r64 OR r/m64.                                                       |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
+
+In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional
+registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this
+section for encoding data and limits.
diff --git a/xanual/pop.md b/xanual/pop.md
new file mode 100755 (executable)
index 0000000..bdc0664
--- /dev/null
@@ -0,0 +1,66 @@
+# POP — Pop a Value from the Stack
+
+## Description
+
+Loads the value from the top of the stack to the location specified with the destination operand (or explicit opcode) and then increments the
+stack pointer. The destination operand can be a general-purpose register, memory location, or segment register.
+
+## Instruction
+
+| Opcode | Assembly    | Op/En | Modern Mode | Legacy Mode | Description                                                                       |
+|--------|-------------|-------|-------------|-------------|-----------------------------------------------------------------------------------|
+| 8F /0  | POP r/m16   | M     | Valid       | Valid       | Pop top of stack into m16, increment stack pointer.                               |
+| 8F /0  | POP r/m32   | M     | N.E.        | Valid       | Pop top of stack into m32, increment stack pointer.                               |
+| 8F /0  | POP r/m64   | M     | Valid       | N.E.        | Pop top of stack into m64, increment stack pointer.                               |
+| 58+rw  | POP r16     | O     | Valid       | Valid       | Pop top of stack into r16, increment stack pointer.                               |
+| 58+rd  | POP r32     | O     | N.E.        | Valid       | Pop top of stack into r32, increment stack pointer.                               |
+| 58+rd  | POP r64     | O     | Valid       | N.E.        | Pop top of stack into r64, increment stack pointer.                               |
+| 1F     | POP DS      | NP    | Invalid     | Valid       | Pop top of stack into DS, increment stack pointer.                                |
+| 07     | POP ES      | NP    | Invalid     | Valid       | Pop top of stack into ES, increment stack pointer.                                |
+| 17     | POP SS      | NP    | Invalid     | Valid       | Pop top of stack into SS, increment stack pointer.                                |
+| 0F A1  | POP FS      | NP    | Valid       | Valid       | Pop top of stack into FS, increment stack pointer by 16 bits.                     |
+| 0F A1  | POP FS      | NP    | N.E.        | Valid       | Pop top of stack into FS, increment stack pointer by 32 bits.                     |
+| 0F A1  | POP FS      | NP    | Valid       | N.E.        | Pop top of stack into FS, increment stack pointer by 64 bits.                     |
+| 0F A9  | POP GS      | NP    | Valid       | Valid       | Pop top of stack into GS, increment stack pointer by 16 bits.                     |
+| 0F A9  | POP GS      | NP    | N.E.        | Valid       | Pop top of stack into GS, increment stack pointer by 32 bits.                     |
+| 0F A9  | POP GS      | NP    | Valid       | N.E.        | Pop top of stack into GS, increment stack pointer by 64 bits.                     |
+
+## Information
+
+Address and operand sizes are determined and used as follows:
+
+- Address size: The D flag in the current code-segment descriptor determines the default address size; it may be overridden by an instruction
+prefix (67H). The address size is used only when writing to a destination operand in memory.
+
+- Operand size: The D flag in the current code-segment descriptor determines the default operand size; it may be overridden by instruction
+prefixes (66H or REX.W). The operand size (16, 32, or 64 bits) determines the amount by which the stack pointer is incremented (2, 4 or 8).
+
+- Stack-address size: Outside of 64-bit mode, the B flag in the current stack-segment descriptor determines the size of the stack pointer (16
+or 32 bits); in 64-bit mode, the size of the stack pointer is always 64 bits.The stack-address size determines the width of the stack pointer
+when reading from the stack in memory and when incrementing the stack pointer. (As stated above, the amount by which the stack pointer is
+incremented is determined by the operand size.)
+
+If the destination operand is one of the segment registers DS, ES, FS, GS, or SS, the value loaded into the register must be a valid segment
+selector. In protected mode, popping a segment selector into a segment register automat- ically causes the descriptor information associated
+with that segment selector to be loaded into the hidden (shadow) part of the segment register and causes the selector and the descriptor
+information to be validated (see the "Operation" section below).
+
+A NULL value (0000-0003) may be popped into the DS, ES, FS, or GS register without causing a general protection fault. However, any subsequent
+attempt to reference a segment whose corresponding segment register is loaded with a NULL value causes a general protection exception (#GP). In
+this situation, no memory reference occurs and the saved value of the segment register is NULL.
+
+The POP instruction cannot pop a value into the CS register. To load the CS register from the stack, use the RET instruction.
+
+If the ESP register is used as a base register for addressing a destination operand in memory, the POP instruction computes the effective
+address of the operand after it increments the ESP register. For the case of a 16-bit stack where ESP wraps to 0H as a result of the POP
+instruction, the resulting location of the memory write is processor- family-specific.
+
+The POP ESP instruction increments the stack pointer (ESP) before data at the old top of stack is written into the destination.
+
+A POP SS instruction inhibits all interrupts, including the NMI interrupt, until after execution of the next instruction. This action allows
+sequential execution of POP SS and MOV ESP, EBP instructions without the danger of having an invalid stack during an interrupt1 . However, use
+of the LSS instruction is the preferred method of loading the SS and ESP registers.
+
+In 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). When in 64-bit mode, POPs using 32-bit
+operands are not encodable and POPs to DS, ES, SS are not valid. See the summary chart at the beginning of this section for encoding data and
+limits.
diff --git a/xanual/push.md b/xanual/push.md
new file mode 100755 (executable)
index 0000000..60ad851
--- /dev/null
@@ -0,0 +1,55 @@
+# PUSH — Push Word, Doubleword or Quadword Onto the Stack
+
+## Description
+
+Decrements the stack pointer and then stores the source operand on the top of the stack.
+
+## Instruction
+
+| Opcode | Assembly    | Op/En | Modern Mode | Legacy Mode | Description                                                                       |
+|--------|-------------|-------|-------------|-------------|-----------------------------------------------------------------------------------|
+| FF /6  | PUSH r/m16  | M     | Valid       | Valid       | Decrement stack pointer, push r/m16 onto top of stack.                            |
+| FF /6  | PUSH r/m32  | M     | N.E.        | Valid       | Decrement stack pointer, push r/m32 onto top of stack.                            |
+| FF /6  | PUSH r/m64  | M     | Valid       | N.E.        | Decrement stack pointer, push r/m64 onto top of stack.                            |
+| 50+rw  | PUSH r16    | O     | Valid       | Valid       | Decrement stack pointer, push r16 onto top of stack.                              |
+| 50+rd  | PUSH r32    | O     | N.E.        | Valid       | Decrement stack pointer, push r32 onto top of stack.                              |
+| 50+rd  | PUSH r64    | O     | Valid       | N.E.        | Decrement stack pointer, push r64 onto top of stack.                              |
+| 6A ib  | PUSH imm8   | I     | Valid       | Valid       | Decrement stack pointer, push imm8 onto top of stack.                             |
+| 68 iw  | PUSH imm16  | I     | Valid       | Valid       | Decrement stack pointer, push imm16 onto top of stack.                            |
+| 68 id  | PUSH imm32  | I     | Valid       | Valid       | Decrement stack pointer, push imm32 onto top of stack.                            |
+| 0E     | PUSH CS     | NP    | Invalid     | Valid       | Decrement stack pointer, push CS onto top of stack.                               |
+| 16     | PUSH SS     | NP    | Invalid     | Valid       | Decrement stack pointer, push SS onto top of stack.                               |
+| 1E     | PUSH DS     | NP    | Invalid     | Valid       | Decrement stack pointer, push DS onto top of stack.                               |
+| 06     | PUSH ES     | NP    | Invalid     | Valid       | Decrement stack pointer, push ES onto top of stack.                               |
+| 0F A0  | PUSH FS     | NP    | Valid       | Valid       | Decrement stack pointer, push FS onto top of stack.                               |
+| 0F A8  | PUSH GS     | NP    | Valid       | Valid       | Decrement stack pointer, push GS onto top of stack.                               |
+
+## Information
+
+Address and operand sizes are determined and used as follows:
+
+- Address size: The D flag in the current code-segment descriptor determines the default address size; it may be overridden by an instruction
+prefix (67H). The address size is used only when referencing a source operand in memory.
+
+- Operand size: The D flag in the current code-segment descriptor determines the default operand size; it may be overridden by instruction
+prefixes (66H or REX.W). The operand size (16, 32, or 64 bits) determines the amount by which the stack pointer is decremented (2, 4 or 8). If
+the source operand is an immediate of size less than the operand size, a sign-extended value is pushed on the stack. If the source operand is a
+segment register (16 bits) and the operand size is 64-bits, a zero- extended value is pushed on the stack; if the operand size is 32-bits,
+either a zero-extended value is pushed on the stack or the segment selector is written on the stack using a 16-bit move. For the last case, all
+recent Core and Atom processors perform a 16-bit move, leaving the upper portion of the stack location unmodified.
+
+- Stack-address size: Outside of 64-bit mode, the B flag in the current stack-segment descriptor determines the size of the stack pointer (16
+or 32 bits); in 64-bit mode, the size of the stack pointer is always 64 bits. The stack-address size determines the width of the stack pointer
+when writing to the stack in memory and when decrementing the stack pointer. (As stated above, the amount by which the stack pointer is
+decremented is determined by the operand size.) If the operand size is less than the stack-address size, the PUSH instruction may result in a
+misaligned stack pointer (a stack pointer that is not aligned on a doubleword or quadword boundary).
+
+The PUSH ESP instruction pushes the value of the ESP register as it existed before the instruction was executed. If a PUSH instruction uses a
+memory operand in which the ESP register is used for computing the operand address, the address of the operand is computed before the ESP
+register is decremented.
+
+If the ESP or SP register is 1 when the PUSH instruction is executed in real-address mode, a stack-fault exception (#SS) is generated (because
+the limit of the stack segment is violated). Its delivery encounters a second stack- fault exception (for the same reason), causing generation
+of a double-fault exception (#DF). Delivery of the double-fault exception encounters a third stack-fault exception, and the logical processor
+enters shutdown mode. See the discussion of the double-fault exception in Chapter 6 of the Intel® 64 and IA-32 Architectures Software
+Developer's Manual, Volume 3A.
diff --git a/xanual/ret.md b/xanual/ret.md
new file mode 100755 (executable)
index 0000000..65aa948
--- /dev/null
@@ -0,0 +1,52 @@
+# RET — Return from Procedure
+
+## Description
+
+Transfers program control to a return address located on the top of the stack. The address is usually placed on the stack by a CALL
+instruction, and the return is made to the instruction that follows the CALL instruction.
+
+## Instruction
+
+| Opcode | Assembly  | Op/En | Modern Mode | Legacy Mode | Description                                                                         |
+|--------|-----------|-------|-------------|-------------|-------------------------------------------------------------------------------------|
+| C3     | RET       | NP    | Valid       | Valid       | Near return to calling procedure.                                                   |
+| CB     | RET       | NP    | Valid       | Valid       | Far return to calling procedure.                                                    |
+| C2 iw  | RET imm16 | I     | Valid       | Valid       | Near return to calling procedure and pop imm16 bytes from stack.                    |
+| CA iw  | RET imm16 | I     | Valid       | Valid       | Far return to calling procedure and pop imm16 bytes from stack.                     |
+
+## Information
+
+The optional source operand specifies the number of stack bytes to be released after the return address is popped; the default is none. This
+operand can be used to release parameters from the stack that were passed to the called procedure and are no longer needed. It must be used
+when the CALL instruction used to switch to a new procedure uses a call gate with a non-zero word count to access the new procedure. Here, the
+source operand for the RET instruction must specify the same number of bytes as is specified in the word count field of the call gate.
+
+The RET instruction can be used to execute three different types of returns:
+
+• Near return — A return to a calling procedure within the current code segment (the segment currently pointed to by the CS register),
+sometimes referred to as an intrasegment return.
+
+• Far return — A return to a calling procedure located in a different segment than the current code segment, sometimes referred to as an
+intersegment return.
+
+• Inter-privilege-level far return — A far return to a different privilege level than that of the currently executing program or procedure.
+
+The inter-privilege-level return type can only be executed in protected mode. See the section titled "Calling Procedures Using Call and RET" in
+Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 1, for detailed information on near, far, and inter
+privilege level returns.
+
+When executing a near return, the processor pops the return instruction pointer (offset) from the top of the stack into the EIP register and
+begins program execution at the new instruction pointer. The CS register is unchanged. When executing a far return, the processor pops the
+return instruction pointer from the top of the stack into the EIP register, then pops the segment selector from the top of the stack into the
+CS register. The processor then begins program execution in the new code segment at the new instruction pointer.
+
+The mechanics of an inter-privilege-level far return are similar to an intersegment return, except that the processor examines the privilege
+levels and access rights of the code and stack segments being returned to determine if the control transfer is allowed to be made. The DS, ES,
+FS, and GS segment registers are cleared by the RET instruction during an inter-privilege-level return if they refer to segments that are not
+allowed to be accessed at the new privilege level. Since a stack switch also occurs on an inter-privilege level return, the ESP and SS
+registers are loaded from the stack.
+
+If parameters are passed to the called procedure during an inter-privilege level call, the optional source operand must be used with the RET
+instruction to release the parameters on the return. Here, the parameters are released both from the called procedure's stack and the calling
+procedure's stack (that is, the stack being returned to). In 64-bit mode, the default operation size of this instruction is the stack-address
+size, i.e. 64 bits. This applies to near returns, not far returns; the default operation size of far returns is 32 bits.
diff --git a/xanual/rot.md b/xanual/rot.md
new file mode 100755 (executable)
index 0000000..9ad236a
--- /dev/null
@@ -0,0 +1,94 @@
+# RCL/RCR/ROL/ROR — Rotate
+
+## Description
+
+Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the second operand (count
+operand) and stores the result in the destination operand. The destination operand can be a register or a memory location; the count operand is
+an unsigned integer that can be an immediate or a value in the CL register. The count is masked to 5 bits (or 6 bits if in 64-bit mode and
+REX.W = 1).
+
+## Instruction
+
+| Opcode           | Assembly        | Op/En | Modern Mode | Legacy Mode | Description                                                         |
+|------------------|-----------------|-------|-------------|-------------|---------------------------------------------------------------------|
+| D0 /2            | RCL r/m8, 1     | M1    | Valid       | Valid       | Rotate 9 bits (CF, r/m8) left once.                                 |
+| REX + D0 /2      | RCL r/m8*, 1    | M1    | Valid       | N.E.        | Rotate 9 bits (CF, r/m8) left once.                                 |
+| D2 /2            | RCL r/m8, CL    | MC    | Valid       | Valid       | Rotate 9 bits (CF, r/m8) left CL times.                             |
+| REX + D2 /2      | RCL r/m8*, CL   | MC    | Valid       | N.E.        | Rotate 9 bits (CF, r/m8) left CL times.                             |
+| C0 /2 ib         | RCL r/m8, imm8  | MI    | Valid       | Valid       | Rotate 9 bits (CF, r/m8) left imm8 times.                           |
+| REX + C0 /2 ib   | RCL r/m8*, imm8 | MI    | Valid       | N.E.        | Rotate 9 bits (CF, r/m8) left imm8 times.                           |
+| D1 /2            | RCL r/m16, 1    | M1    | Valid       | Valid       | Rotate 17 bits (CF, r/m16) left once.                               |
+| D3 /2            | RCL r/m16, CL   | MC    | Valid       | Valid       | Rotate 17 bits (CF, r/m16) left CL times.                           |
+| C1 /2 ib         | RCL r/m16, imm8 | MI    | Valid       | Valid       | Rotate 17 bits (CF, r/m16) left imm8 times.                         |
+| D1 /2            | RCL r/m32, 1    | M1    | Valid       | Valid       | Rotate 33 bits (CF, r/m32) left once.                               |
+| REX.W + D1 /2    | RCL r/m64, 1    | M1    | Valid       | N.E.        | Rotate 65 bits (CF, r/m64) left once.                               |
+| D3 /2            | RCL r/m32, CL   | MC    | Valid       | Valid       | Rotate 33 bits (CF, r/m32) left CL times.                           |
+| REX.W + D3 /2    | RCL r/m64, CL   | MC    | Valid       | N.E.        | Rotate 65 bits (CF, r/m64) left CL times.                           |
+| C1 /2 ib         | RCL r/m32, imm8 | MI    | Valid       | Valid       | Rotate 33 bits (CF, r/m32) left imm8 times.                         |
+| REX.W + C1 /2 ib | RCL r/m64, imm8 | MI    | Valid       | N.E.        | Rotate 65 bits (CF, r/m64) left imm8 times.                         |
+| D0 /3            | RCR r/m8, 1     | M1    | Valid       | Valid       | Rotate 9 bits (CF, r/m8) right once.                                |
+| REX + D0 /3      | RCR r/m8*, 1    | M1    | Valid       | N.E.        | Rotate 9 bits (CF, r/m8) right once.                                |
+| D2 /3            | RCR r/m8, CL    | MC    | Valid       | Valid       | Rotate 9 bits (CF, r/m8) right CL times.                            |
+| REX + D2 /3      | RCR r/m8*, CL   | MC    | Valid       | N.E.        | Rotate 9 bits (CF, r/m8) right CL times.                            |
+| C0 /3 ib         | RCR r/m8, imm8  | MI    | Valid       | Valid       | Rotate 9 bits (CF, r/m8) right imm8 times.                          |
+| REX + C0 /3 ib   | RCR r/m8*, imm8 | MI    | Valid       | N.E.        | Rotate 9 bits (CF, r/m8) right imm8 times.                          |
+| D1 /3            | RCR r/m16, 1    | M1    | Valid       | Valid       | Rotate 17 bits (CF, r/m16) right once.                              |
+| D3 /3            | RCR r/m16, CL   | MC    | Valid       | Valid       | Rotate 17 bits (CF, r/m16) right CL times.                          |
+| C1 /3 ib         | RCR r/m16, imm8 | MI    | Valid       | Valid       | Rotate 17 bits (CF, r/m16) right imm8 times.                        |
+| D1 /3            | RCR r/m32, 1    | M1    | Valid       | Valid       | Rotate 33 bits (CF, r/m32) right once.                              |
+| REX.W + D1 /3    | RCR r/m64, 1    | M1    | Valid       | N.E.        | Rotate 65 bits (CF, r/m64) right once.                              |
+| D3 /3            | RCR r/m32, CL   | MC    | Valid       | Valid       | Rotate 33 bits (CF, r/m32) right CL times.                          |
+| REX.W + D3 /3    | RCR r/m64, CL   | MC    | Valid       | N.E.        | Rotate 65 bits (CF, r/m64) right CL times.                          |
+| C1 /3 ib         | RCR r/m32, imm8 | MI    | Valid       | Valid       | Rotate 33 bits (CF, r/m32) right imm8 times.                        |
+| REX.W + C1 /3 ib | RCR r/m64, imm8 | MI    | Valid       | N.E.        | Rotate 65 bits (CF, r/m64) right imm8 times.                        |
+| D0 /0            | ROL r/m8, 1     | M1    | Valid       | Valid       | Rotate 8 bits r/m8 left once.                                       |
+| REX + D0 /0      | ROL r/m8*, 1    | M1    | Valid       | N.E.        | Rotate 8 bits r/m8 left once                                        |
+| D2 /0            | ROL r/m8, CL    | MC    | Valid       | Valid       | Rotate 8 bits r/m8 left CL times.                                   |
+| REX + D2 /0      | ROL r/m8*, CL   | MC    | Valid       | N.E.        | Rotate 8 bits r/m8 left CL times.                                   |
+| C0 /0 ib         | ROL r/m8, imm8  | MI    | Valid       | Valid       | Rotate 8 bits r/m8 left imm8 times.                                 |
+| REX + C0 /0 ib   | ROL r/m8*, imm8 | MI    | Valid       | N.E.        | Rotate 8 bits r/m8 left imm8 times.                                 |
+| D1 /0            | ROL r/m16, 1    | M1    | Valid       | Valid       | Rotate 16 bits r/m16 left once.                                     |
+| D3 /0            | ROL r/m16, CL   | MC    | Valid       | Valid       | Rotate 16 bits r/m16 left CL times.                                 |
+| C1 /0 ib         | ROL r/m16, imm8 | MI    | Valid       | Valid       | Rotate 16 bits r/m16 left imm8 times.                               |
+| D1 /0            | ROL r/m32, 1    | M1    | Valid       | Valid       | Rotate 32 bits r/m32 left once.                                     |
+| REX.W + D1 /0    | ROL r/m64, 1    | M1    | Valid       | N.E.        | Rotate 64 bits r/m64 left once.                                     |
+| D3 /0            | ROL r/m32, CL   | MC    | Valid       | Valid       | Rotate 32 bits r/m32 left CL times.                                 |
+| REX.W + D3 /0    | ROL r/m64, CL   | MC    | Valid       | N.E.        | Rotate 64 bits r/m64 left CL times.                                 |
+| C1 /0 ib         | ROL r/m32, imm8 | MI    | Valid       | Valid       | Rotate 32 bits r/m32 left imm8 times.                               |
+| REX.W + C1 /0 ib | ROL r/m64, imm8 | MI    | Valid       | N.E.        | Rotate 64 bits r/m64 left imm8 times.                               |
+| D0 /1            | ROR r/m8, 1     | M1    | Valid       | Valid       | Rotate 8 bits r/m8 right once.                                      |
+| REX + D0 /1      | ROR r/m8*, 1    | M1    | Valid       | N.E.        | Rotate 8 bits r/m8 right once.                                      |
+| D2 /1            | ROR r/m8, CL    | MC    | Valid       | Valid       | Rotate 8 bits r/m8 right CL times.                                  |
+| REX + D2 /1      | ROR r/m8*, CL   | MC    | Valid       | N.E.        | Rotate 8 bits r/m8 right CL times.                                  |
+| C0 /1 ib         | ROR r/m8, imm8  | MI    | Valid       | Valid       | Rotate 8 bits r/m16 right imm8 times.                               |
+| REX + C0 /1 ib   | ROR r/m8*, imm8 | MI    | Valid       | N.E.        | Rotate 8 bits r/m16 right imm8 times.                               |
+| D1 /1            | ROR r/m16, 1    | M1    | Valid       | Valid       | Rotate 16 bits r/m16 right once.                                    |
+| D3 /1            | ROR r/m16, CL   | MC    | Valid       | Valid       | Rotate 16 bits r/m16 right CL times.                                |
+| C1 /1 ib         | ROR r/m16, imm8 | MI    | Valid       | Valid       | Rotate 16 bits r/m16 right imm8 times.                              |
+| D1 /1            | ROR r/m32, 1    | M1    | Valid       | Valid       | Rotate 32 bits r/m32 right once.                                    |
+| REX.W + D1 /1    | ROR r/m64, 1    | M1    | Valid       | N.E.        | Rotate 64 bits r/m64 right once.                                    |
+| D3 /1            | ROR r/m32, CL   | MC    | Valid       | Valid       | Rotate 32 bits r/m32 right CL times.                                |
+| REX.W + D3 /1    | ROR r/m64, CL   | MC    | Valid       | N.E.        | Rotate 64 bits r/m64 right CL times.                                |
+| C1 /1 ib         | ROR r/m32, imm8 | MI    | Valid       | Valid       | Rotate 32 bits r/m32 right imm8 times.                              |
+| REX.W + C1 /1 ib | ROR r/m64, imm8 | MI    | Valid       | N.E.        | Rotate 64 bits r/m64 right imm8 times.                              |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+The rotate left (ROL) and rotate through carry left (RCL) instructions shift all the bits toward more-significant bit positions, except for the
+most-significant bit, which is rotated to the least-significant bit location. The rotate right (ROR) and rotate through carry right (RCR)
+instructions shift all the bits toward less significant bit positions, except for the least-significant bit, which is rotated to the
+most-significant bit location.
+
+The RCL and RCR instructions include the CF flag in the rotation. The RCL instruction shifts the CF flag into the least-significant bit and
+shifts the most-significant bit into the CF flag. The RCR instruction shifts the CF flag into the most-significant bit and shifts the
+least-significant bit into the CF flag. For the ROL and ROR instructions, the original value of the CF flag is not a part of the result, but
+the CF flag receives a copy of the bit that was shifted from one end to the other.
+
+The OF flag is defined only for the 1-bit rotates; it is undefined in all other cases (except RCL and RCR instructions only: a zero-bit rotate
+does nothing, that is affects no flags). For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the
+most-significant bit of the result. For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.
+
+In 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Use of REX.W promotes the first
+operand to 64 bits and causes the count operand to become a 6-bit counter.
diff --git a/xanual/sbb.md b/xanual/sbb.md
new file mode 100755 (executable)
index 0000000..537839d
--- /dev/null
@@ -0,0 +1,54 @@
+# SBB — Subtraction with Borrow
+
+## Description
+
+Adds the source operand (second operand) and the carry (CF) flag, and subtracts the result from the destination operand (first operand). The
+result of the subtraction is stored in the destination operand. The destination operand can be a register or a memory location; the source
+operand can be an immediate, a register, or a memory location. However, two memory operands cannot be used in one instruction. The state of
+the CF flag represents a borrow from a previous subtraction.
+
+## Instruction
+
+| Opcode           | Assembly         | Op/En | Modern Mode | Legacy Mode | Description                                                        |
+|------------------|------------------|-------|-------------|-------------|--------------------------------------------------------------------|
+| 1C ib            | SBB AL, imm8     | I     | Valid       | Valid       | Subtract with borrow imm8 from AL.                                 |
+| 1D iw            | SBB AX, imm16    | I     | Valid       | Valid       | Subtract with borrow imm16 from AX.                                |
+| 1D id            | SBB EAX, imm32   | I     | Valid       | Valid       | Subtract with borrow imm32 from EAX.                               |
+| REX.W + 1D id    | SBB RAX, imm32   | I     | Valid       | N.E.        | Subtract with borrow sign-extended imm32 to 64-bits from RAX.      |
+| 80 /3 ib         | SBB r/m8, imm8   | MI    | Valid       | Valid       | Subtract with borrow imm8 from r/m8.                               |
+| REX + 80 /3 ib   | SBB r/m8*, imm8  | MI    | Valid       | N.E.        | Subtract with borrow imm8 from r/m8.                               |
+| 81 /3 iw         | SBB r/m16, imm16 | MI    | Valid       | Valid       | Subtract with borrow imm16 from r/m16.                             |
+| 81 /3 id         | SBB r/m32, imm32 | MI    | Valid       | Valid       | Subtract with borrow imm32 from r/m32.                             |
+| REX.W + 81 /3 id | SBB r/m64, imm32 | MI    | Valid       | N.E.        | Subtract with borrow sign-extended imm32 to 64-bits from r/m64.    |
+| 83 /3 ib         | SBB r/m16, imm8  | MI    | Valid       | Valid       | Subtract with borrow sign-extended imm8 from r/m16.                |
+| 83 /3 ib         | SBB r/m32, imm8  | MI    | Valid       | Valid       | Subtract with borrow sign-extended imm8 from r/m32.                |
+| REX.W + 83 /3 ib | SBB r/m64, imm8  | MI    | Valid       | N.E.        | Subtract with borrow sign-extended imm8 from r/m64.                |
+| 18 /r            | SBB r/m8, r8     | MR    | Valid       | Valid       | Subtract with borrow r8 from r/m8.                                 |
+| REX + 18 /r      | SBB r/m8*, r8    | MR    | Valid       | N.E.        | Subtract with borrow r8 from r/m8.                                 |
+| 19 /r            | SBB r/m16, r16   | MR    | Valid       | Valid       | Subtract with borrow r16 from r/m16.                               |
+| 19 /r            | SBB r/m32, r32   | MR    | Valid       | Valid       | Subtract with borrow r32 from r/m32.                               |
+| REX.W + 19 /r    | SBB r/m64, r64   | MR    | Valid       | N.E.        | Subtract with borrow r64 from r/m64.                               |
+| 1A /r            | SBB r8, r/m8     | RM    | Valid       | Valid       | Subtract with borrow r/m8 from r8.                                 |
+| REX + 1A /r      | SBB r8*, r/m8*   | RM    | Valid       | N.E.        | Subtract with borrow r/m8 from r8.                                 |
+| 1B /r            | SBB r16, r/m16   | RM    | Valid       | Valid       | Subtract with borrow r/m16 from r16.                               |
+| 1B /r            | SBB r32, r/m32   | RM    | Valid       | Valid       | Subtract with borrow r/m32 from r32.                               |
+| REX.W + 1B /r    | SBB r64, r/m64   | RM    | Valid       | N.E.        | Subtract with borrow r/m64 from r64.                               |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
+
+When an immediate value is used as an operand, it is sign-extended to the length of the destination operand format.
+
+The SBB instruction does not distinguish between signed or unsigned operands. Instead, the processor evaluates the result for both data types
+and sets the OF and CF flags to indicate a borrow in the signed or unsigned result, respectively. The SF flag indicates the sign of the signed
+result.
+
+The SBB instruction is usually executed as part of a multibyte or multiword subtraction in which a SUB instruction is followed by a SBB
+instruction.
+
+In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional
+registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this
+section for encoding data and limits.
diff --git a/xanual/setcc.md b/xanual/setcc.md
new file mode 100755 (executable)
index 0000000..79c815e
--- /dev/null
@@ -0,0 +1,89 @@
+# SETcc — Set Byte on Condition
+
+## Description
+
+Sets the destination operand to 0 or 1 depending on the settings of the status flags (CF, SF, OF, ZF, and PF) in the EFLAGS register. The
+destination operand points to a byte register or a byte in memory. The condition code suffix (cc) indicates the condition being tested for.
+
+## Instruction
+
+| Opcode      | Assembly     | Op/En | Modern Mode | Legacy Mode | Description                                                                 |
+|-------------|--------------|-------|-------------|-------------|-----------------------------------------------------------------------------|
+| 0F 97       | SETA r/m8    | M     | Valid       | Valid       | Set byte if above (CF=0 and ZF=0).                                          |
+| REX + 0F 97 | SETA r/m8*   | M     | Valid       | N.E.        | Set byte if above (CF=0 and ZF=0).                                          |
+| 0F 93       | SETAE r/m8   | M     | Valid       | Valid       | Set byte if above or equal (CF=0).                                          |
+| REX + 0F 93 | SETAE r/m8*  | M     | Valid       | N.E.        | Set byte if above or equal (CF=0).                                          |
+| 0F 92       | SETB r/m8    | M     | Valid       | Valid       | Set byte if below (CF=1).                                                   |
+| REX + 0F 92 | SETB r/m8*   | M     | Valid       | N.E.        | Set byte if below (CF=1).                                                   |
+| 0F 96       | SETBE r/m8   | M     | Valid       | Valid       | Set byte if below or equal (CF=1 or ZF=1).                                  |
+| REX + 0F 96 | SETBE r/m8*  | M     | Valid       | N.E.        | Set byte if below or equal (CF=1 or ZF=1).                                  |
+| 0F 92       | SETC r/m8    | M     | Valid       | Valid       | Set byte if carry (CF=1).                                                   |
+| REX + 0F 92 | SETC r/m8*   | M     | Valid       | N.E.        | Set byte if carry (CF=1).                                                   |
+| 0F 94       | SETE r/m8    | M     | Valid       | Valid       | Set byte if equal (ZF=1).                                                   |
+| REX + 0F 94 | SETE r/m8*   | M     | Valid       | N.E.        | Set byte if equal (ZF=1).                                                   |
+| 0F 9F       | SETG r/m8    | M     | Valid       | Valid       | Set byte if greater (ZF=0 and SF=OF).                                       |
+| REX + 0F 9F | SETG r/m8*   | M     | Valid       | N.E.        | Set byte if greater (ZF=0 and SF=OF).                                       |
+| 0F 9D       | SETGE r/m8   | M     | Valid       | Valid       | Set byte if greater or equal (SF=OF).                                       |
+| REX + 0F 9D | SETGE r/m8*  | M     | Valid       | N.E.        | Set byte if greater or equal (SF=OF).                                       |
+| 0F 9C       | SETL r/m8    | M     | Valid       | Valid       | Set byte if less (SF≠ OF).                                                  |
+| REX + 0F 9C | SETL r/m8*   | M     | Valid       | N.E.        | Set byte if less (SF≠ OF).                                                  |
+| 0F 9E       | SETLE r/m8   | M     | Valid       | Valid       | Set byte if less or equal (ZF=1 or SF≠ OF).                                 |
+| REX + 0F 9E | SETLE r/m8*  | M     | Valid       | N.E.        | Set byte if less or equal (ZF=1 or SF≠ OF).                                 |
+| 0F 96       | SETNA r/m8   | M     | Valid       | Valid       | Set byte if not above (CF=1 or ZF=1).                                       |
+| REX + 0F 96 | SETNA r/m8*  | M     | Valid       | N.E.        | Set byte if not above (CF=1 or ZF=1).                                       |
+| 0F 92       | SETNAE r/m8  | M     | Valid       | Valid       | Set byte if not above or equal (CF=1).                                      |
+| REX + 0F 92 | SETNAE r/m8* | M     | Valid       | N.E.        | Set byte if not above or equal (CF=1).                                      |
+| 0F 93       | SETNB r/m8   | M     | Valid       | Valid       | Set byte if not below (CF=0).                                               |
+| REX + 0F 93 | SETNB r/m8*  | M     | Valid       | N.E.        | Set byte if not below (CF=0).                                               |
+| 0F 97       | SETNBE r/m8  | M     | Valid       | Valid       | Set byte if not below or equal (CF=0 and ZF=0).                             |
+| REX + 0F 97 | SETNBE r/m8* | M     | Valid       | N.E.        | Set byte if not below or equal (CF=0 and ZF=0).                             |
+| 0F 93       | SETNC r/m8   | M     | Valid       | Valid       | Set byte if not carry (CF=0).                                               |
+| REX + 0F 93 | SETNC r/m8*  | M     | Valid       | N.E.        | Set byte if not carry (CF=0).                                               |
+| 0F 95       | SETNE r/m8   | M     | Valid       | Valid       | Set byte if not equal (ZF=0).                                               |
+| REX + 0F 95 | SETNE r/m8*  | M     | Valid       | N.E.        | Set byte if not equal (ZF=0).                                               |
+| 0F 9E       | SETNG r/m8   | M     | Valid       | Valid       | Set byte if not greater (ZF=1 or SF≠ OF)                                    |
+| REX + 0F 9E | SETNG r/m8*  | M     | Valid       | N.E.        | Set byte if not greater (ZF=1 or SF≠ OF).                                   |
+| 0F 9C       | SETNGE r/m8  | M     | Valid       | Valid       | Set byte if not greater or equal (SF≠ OF).                                  |
+| REX + 0F 9C | SETNGE r/m8* | M     | Valid       | N.E.        | Set byte if not greater or equal (SF≠ OF).                                  |
+| 0F 9D       | SETNL r/m8   | M     | Valid       | Valid       | Set byte if not less (SF=OF).                                               |
+| REX + 0F 9D | SETNL r/m8*  | M     | Valid       | N.E.        | Set byte if not less (SF=OF).                                               |
+| 0F 9F       | SETNLE r/m8  | M     | Valid       | Valid       | Set byte if not less or equal (ZF=0 and SF=OF).                             |
+| REX + 0F 9F | SETNLE r/m8* | M     | Valid       | N.E.        | Set byte if not less or equal (ZF=0 and SF=OF).                             |
+| 0F 91       | SETNO r/m8   | M     | Valid       | Valid       | Set byte if not overflow (OF=0).                                            |
+| REX + 0F 91 | SETNO r/m8*  | M     | Valid       | N.E.        | Set byte if not overflow (OF=0).                                            |
+| 0F 9B       | SETNP r/m8   | M     | Valid       | Valid       | Set byte if not parity (PF=0).                                              |
+| REX + 0F 9B | SETNP r/m8*  | M     | Valid       | N.E.        | Set byte if not parity (PF=0).                                              |
+| 0F 99       | SETNS r/m8   | M     | Valid       | Valid       | Set byte if not sign (SF=0).                                                |
+| REX + 0F 99 | SETNS r/m8*  | M     | Valid       | N.E.        | Set byte if not sign (SF=0).                                                |
+| 0F 95       | SETNZ r/m8   | M     | Valid       | Valid       | Set byte if not zero (ZF=0).                                                |
+| REX + 0F 95 | SETNZ r/m8*  | M     | Valid       | N.E.        | Set byte if not zero (ZF=0).                                                |
+| 0F 90       | SETO r/m8    | M     | Valid       | Valid       | Set byte if overflow (OF=1)                                                 |
+| REX + 0F 90 | SETO r/m8*   | M     | Valid       | N.E.        | Set byte if overflow (OF=1).                                                |
+| 0F 9A       | SETP r/m8    | M     | Valid       | Valid       | Set byte if parity (PF=1).                                                  |
+| REX + 0F 9A | SETP r/m8*   | M     | Valid       | N.E.        | Set byte if parity (PF=1).                                                  |
+| 0F 9A       | SETPE r/m8   | M     | Valid       | Valid       | Set byte if parity even (PF=1).                                             |
+| REX + 0F 9A | SETPE r/m8*  | M     | Valid       | N.E.        | Set byte if parity even (PF=1).                                             |
+| 0F 9B       | SETPO r/m8   | M     | Valid       | Valid       | Set byte if parity odd (PF=0).                                              |
+| REX + 0F 9B | SETPO r/m8*  | M     | Valid       | N.E.        | Set byte if parity odd (PF=0).                                              |
+| 0F 98       | SETS r/m8    | M     | Valid       | Valid       | Set byte if sign (SF=1).                                                    |
+| REX + 0F 98 | SETS r/m8*   | M     | Valid       | N.E.        | Set byte if sign (SF=1).                                                    |
+| 0F 94       | SETZ r/m8    | M     | Valid       | Valid       | Set byte if zero (ZF=1).                                                    |
+| REX + 0F 94 | SETZ r/m8*   | M     | Valid       | N.E.        | Set byte if zero (ZF=1).                                                    |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+The terms “above” and “below” are associated with the CF flag and refer to the relationship between two unsigned integer values. The terms
+“greater” and “less” are associated with the SF and OF flags and refer to the relationship between two signed integer values.
+
+Many of the SETcc instruction opcodes have alternate mnemonics. For example, SETG (set byte if greater) and SETNLE (set if not less or equal)
+have the same opcode and test for the same condition: ZF equals 0 and SF equals OF. These alternate mnemonics are provided to make code more
+intelligible.
+
+Some languages represent a logical one as an integer with all bits set. This representation can be obtained by choosing the logically opposite
+condition for the SETcc instruction, then decrementing the result. For example, to test for overflow, use the SETNO instruction, then decrement
+the result.
+
+In IA-64 mode, the operand size is fixed at 8 bits. Use of REX prefix enable uniform addressing to additional byte registers. Otherwise, this
+instruction’s operation is the same as in legacy mode and compatibility mode.
diff --git a/xanual/sft.md b/xanual/sft.md
new file mode 100755 (executable)
index 0000000..a053948
--- /dev/null
@@ -0,0 +1,110 @@
+# SAL/SAR/SHL/SHR — Shift
+
+## Description
+
+Shifts the bits in the first operand (destination operand) to the left or right by the number of bits specified in the second operand (count
+operand). Bits shifted beyond the destination operand boundary are first shifted into the CF flag, then discarded. At the end of the shift
+operation, the CF flag contains the last bit shifted out of the destination operand.
+
+## Instruction
+
+| Opcode           | Assembly         | Op/En | Modern Mode | Legacy Mode | Description                                                        |
+|------------------|------------------|-------|-------------|-------------|--------------------------------------------------------------------|
+| D0 /4            | SAL r/m8, 1      | M1    | Valid       | Valid       | Multiply r/m8 by 2, once.                                          |
+| REX + D0 /4      | SAL r/m8**, 1    | M1    | Valid       | N.E.        | Multiply r/m8 by 2, once.                                          |
+| D2 /4            | SAL r/m8, CL     | MC    | Valid       | Valid       | Multiply r/m8 by 2, CL times.                                      |
+| REX + D2 /4      | SAL r/m8**, CL   | MC    | Valid       | N.E.        | Multiply r/m8 by 2, CL times.                                      |
+| C0 /4 ib         | SAL r/m8, imm8   | MI    | Valid       | Valid       | Multiply r/m8 by 2, imm8 times.                                    |
+| REX + C0 /4 ib   | SAL r/m8**, imm8 | MI    | Valid       | N.E.        | Multiply r/m8 by 2, imm8 times.                                    |
+| D1 /4            | SAL r/m16, 1     | M1    | Valid       | Valid       | Multiply r/m16 by 2, once.                                         |
+| D3 /4            | SAL r/m16, CL    | MC    | Valid       | Valid       | Multiply r/m16 by 2, CL times.                                     |
+| C1 /4 ib         | SAL r/m16, imm8  | MI    | Valid       | Valid       | Multiply r/m16 by 2, imm8 times.                                   |
+| D1 /4            | SAL r/m32, 1     | M1    | Valid       | Valid       | Multiply r/m32 by 2, once.                                         |
+| REX.W + D1 /4    | SAL r/m64, 1     | M1    | Valid       | N.E.        | Multiply r/m64 by 2, once.                                         |
+| D3 /4            | SAL r/m32, CL    | MC    | Valid       | Valid       | Multiply r/m32 by 2, CL times.                                     |
+| REX.W + D3 /4    | SAL r/m64, CL    | MC    | Valid       | N.E.        | Multiply r/m64 by 2, CL times.                                     |
+| C1 /4 ib         | SAL r/m32, imm8  | MI    | Valid       | Valid       | Multiply r/m32 by 2, imm8 times.                                   |
+| REX.W + C1 /4 ib | SAL r/m64, imm8  | MI    | Valid       | N.E.        | Multiply r/m64 by 2, imm8 times.                                   |
+| D0 /7            | SAR r/m8, 1      | M1    | Valid       | Valid       | Signed divide* r/m8 by 2, once.                                    |
+| REX + D0 /7      | SAR r/m8**, 1    | M1    | Valid       | N.E.        | Signed divide* r/m8 by 2, once.                                    |
+| D2 /7            | SAR r/m8, CL     | MC    | Valid       | Valid       | Signed divide* r/m8 by 2, CL times.                                |
+| REX + D2 /7      | SAR r/m8**, CL   | MC    | Valid       | N.E.        | Signed divide* r/m8 by 2, CL times.                                |
+| C0 /7 ib         | SAR r/m8, imm8   | MI    | Valid       | Valid       | Signed divide* r/m8 by 2, imm8 time.                               |
+| REX + C0 /7 ib   | SAR r/m8**, imm8 | MI    | Valid       | N.E.        | Signed divide* r/m8 by 2, imm8 times.                              |
+| D1 /7            | SAR r/m16,1      | M1    | Valid       | Valid       | Signed divide* r/m16 by 2, once.                                   |
+| D3 /7            | SAR r/m16, CL    | MC    | Valid       | Valid       | Signed divide* r/m16 by 2, CL times.                               |
+| C1 /7 ib         | SAR r/m16, imm8  | MI    | Valid       | Valid       | Signed divide* r/m16 by 2, imm8 times.                             |
+| D1 /7            | SAR r/m32, 1     | M1    | Valid       | Valid       | Signed divide* r/m32 by 2, once.                                   |
+| REX.W + D1 /7    | SAR r/m64, 1     | M1    | Valid       | N.E.        | Signed divide* r/m64 by 2, once.                                   |
+| D3 /7            | SAR r/m32, CL    | MC    | Valid       | Valid       | Signed divide* r/m32 by 2, CL times.                               |
+| REX.W + D3 /7    | SAR r/m64, CL    | MC    | Valid       | N.E.        | Signed divide* r/m64 by 2, CL times.                               |
+| C1 /7 ib         | SAR r/m32, imm8  | MI    | Valid       | Valid       | Signed divide* r/m32 by 2, imm8 times.                             |
+| REX.W + C1 /7 ib | SAR r/m64, imm8  | MI    | Valid       | N.E.        | Signed divide* r/m64 by 2, imm8 times                              |
+| D0 /4            | SHL r/m8, 1      | M1    | Valid       | Valid       | Multiply r/m8 by 2, once.                                          |
+| REX + D0 /4      | SHL r/m8**, 1    | M1    | Valid       | N.E.        | Multiply r/m8 by 2, once.                                          |
+| D2 /4            | SHL r/m8, CL     | MC    | Valid       | Valid       | Multiply r/m8 by 2, CL times.                                      |
+| REX + D2 /4      | SHL r/m8**, CL   | MC    | Valid       | N.E.        | Multiply r/m8 by 2, CL times.                                      |
+| C0 /4 ib         | SHL r/m8, imm8   | MI    | Valid       | Valid       | Multiply r/m8 by 2, imm8 times.                                    |
+| REX + C0 /4 ib   | SHL r/m8**, imm8 | MI    | Valid       | N.E.        | Multiply r/m8 by 2, imm8 times.                                    |
+| D1 /4            | SHL r/m16,1      | M1    | Valid       | Valid       | Multiply r/m16 by 2, once.                                         |
+| D3 /4            | SHL r/m16, CL    | MC    | Valid       | Valid       | Multiply r/m16 by 2, CL times.                                     |
+| C1 /4 ib         | SHL r/m16, imm8  | MI    | Valid       | Valid       | Multiply r/m16 by 2, imm8 times.                                   |
+| D1 /4            | SHL r/m32,1      | M1    | Valid       | Valid       | Multiply r/m32 by 2, once.                                         |
+| REX.W + D1 /4    | SHL r/m64,1      | M1    | Valid       | N.E.        | Multiply r/m64 by 2, once.                                         |
+| D3 /4            | SHL r/m32, CL    | MC    | Valid       | Valid       | Multiply r/m32 by 2, CL times.                                     |
+| REX.W + D3 /4    | SHL r/m64, CL    | MC    | Valid       | N.E.        | Multiply r/m64 by 2, CL times.                                     |
+| C1 /4 ib         | SHL r/m32, imm8  | MI    | Valid       | Valid       | Multiply r/m32 by 2, imm8 times.                                   |
+| REX.W + C1 /4 ib | SHL r/m64, imm8  | MI    | Valid       | N.E.        | Multiply r/m64 by 2, imm8 times.                                   |
+| D0 /5            | SHR r/m8,1       | M1    | Valid       | Valid       | Unsigned divide r/m8 by 2, once.                                   |
+| REX + D0 /5      | SHR r/m8**, 1    | M1    | Valid       | N.E.        | Unsigned divide r/m8 by 2, once.                                   |
+| D2 /5            | SHR r/m8, CL     | MC    | Valid       | Valid       | Unsigned divide r/m8 by 2, CL times.                               |
+| REX + D2 /5      | SHR r/m8**, CL   | MC    | Valid       | N.E.        | Unsigned divide r/m8 by 2, CL times.                               |
+| C0 /5 ib         | SHR r/m8, imm8   | MI    | Valid       | Valid       | Unsigned divide r/m8 by 2, imm8 times.                             |
+| REX + C0 /5 ib   | SHR r/m8**, imm8 | MI    | Valid       | N.E.        | Unsigned divide r/m8 by 2, imm8 times.                             |
+| D1 /5            | SHR r/m16, 1     | M1    | Valid       | Valid       | Unsigned divide r/m16 by 2, once.                                  |
+| D3 /5            | SHR r/m16, CL    | MC    | Valid       | Valid       | Unsigned divide r/m16 by 2, CL times                               |
+| C1 /5 ib         | SHR r/m16, imm8  | MI    | Valid       | Valid       | Unsigned divide r/m16 by 2, imm8 times.                            |
+| D1 /5            | SHR r/m32, 1     | M1    | Valid       | Valid       | Unsigned divide r/m32 by 2, once.                                  |
+| REX.W + D1 /5    | SHR r/m64, 1     | M1    | Valid       | N.E.        | Unsigned divide r/m64 by 2, once.                                  |
+| D3 /5            | SHR r/m32, CL    | MC    | Valid       | Valid       | Unsigned divide r/m32 by 2, CL times.                              |
+| REX.W + D3 /5    | SHR r/m64, CL    | MC    | Valid       | N.E.        | Unsigned divide r/m64 by 2, CL times.                              |
+| C1 /5 ib         | SHR r/m32, imm8  | MI    | Valid       | Valid       | Unsigned divide r/m32 by 2, imm8 times.                            |
+| REX.W + C1 /5 ib | SHR r/m64, imm8  | MI    | Valid       | N.E.        | Unsigned divide r/m64 by 2, imm8 times.                            |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+- Not the same form of division as IDIV; rounding is toward negative infinity.
+
+## Information
+
+The destination operand can be a register or a memory location. The count operand can be an immediate value or the CL register. The count is
+masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is
+used). A special opcode encoding is provided for a count of 1.
+
+The shift arithmetic left (SAL) and shift logical left (SHL) instructions perform the same operation; they shift the bits in the destination
+operand to the left (toward more significant bit locations). For each shift count, the most significant bit of the destination operand is
+shifted into the CF flag, and the least significant bit is cleared.
+
+The shift arithmetic right (SAR) and shift logical right (SHR) instructions shift the bits of the destination operand to the right (toward less
+significant bit locations). For each shift count, the least significant bit of the destination operand is shifted into the CF flag, and the
+most significant bit is either set or cleared depending on the instruction type. The SHR instruction clears the most significant bit (see
+Figure 7-8 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1); the SAR instruction sets or clears the most
+significant bit to correspond to the sign (most significant bit) of the original value in the destination operand. In effect, the SAR
+instruction fills the empty bit position’s shifted value with the sign of the unshifted value.
+
+The SAR and SHR instructions can be used to perform signed or unsigned division, respectively, of the destination operand by powers of 2. For
+example, using the SAR instruction to shift a signed integer 1 bit to the right divides the value by 2.
+
+Using the SAR instruction to perform a division operation does not produce the same result as the IDIV instruction. The quotient from the IDIV
+instruction is rounded toward zero, whereas the “quotient” of the SAR instruction is rounded toward negative infinity. This difference is
+apparent only for negative numbers. For example, when the IDIV instruction is used to divide -9 by 4, the result is -2 with a remainder of -1.
+If the SAR instruction is used to shift -9 right by two bits, the result is -3 and the “remainder” is +3; however, the SAR instruction stores
+only the most significant bit of the remainder (in the CF flag).
+
+The OF flag is affected only on 1-bit shifts. For left shifts, the OF flag is set to 0 if the most-significant bit of the result is the same as
+the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1. For the SAR instruction, the OF flag
+is cleared for all 1-bit shifts. For the SHR instruction, the OF flag is set to the most-significant bit of the original operand.
+
+In 64-bit mode, the instruction’s default operation size is 32 bits and the mask width for CL is 5 bits. Using a REX prefix in the form of
+REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64-bits and sets the mask
+width for CL to 6 bits. See the summary chart at the beginning of this section for encoding data and limits.
diff --git a/xanual/sub.md b/xanual/sub.md
new file mode 100755 (executable)
index 0000000..179b2ec
--- /dev/null
@@ -0,0 +1,48 @@
+# SUB — Subtract
+
+## Description
+
+Subtracts the second operand (source operand) from the first operand (destination operand) and stores the result in the destination operand.
+The destination operand can be a register or a memory location; the source operand can be an immediate, register, or memory location. However,
+two memory operands cannot be used in one instruction. When an immediate value is used as an operand, it is sign-extended to the length of the
+destination operand format.
+
+## Instruction
+
+| Opcode           | Assembly         | Op/En | Modern Mode | Legacy Mode | Description                                                        |
+|------------------|------------------|-------|-------------|-------------|--------------------------------------------------------------------|
+| 2C ib            | SUB AL, imm8     | I     | Valid       | Valid       | Subtract imm8 from AL.                                             |
+| 2D iw            | SUB AX, imm16    | I     | Valid       | Valid       | Subtract imm16 from AX.                                            |
+| 2D id            | SUB EAX, imm32   | I     | Valid       | Valid       | Subtract imm32 from EAX.                                           |
+| REX.W + 2D id    | SUB RAX, imm32   | I     | Valid       | N.E.        | Subtract imm32 sign-extended to 64-bits from RAX.                  |
+| 80 /5 ib         | SUB r/m8, imm8   | MI    | Valid       | Valid       | Subtract imm8 from r/m8.                                           |
+| REX + 80 /5 ib   | SUB r/m8*, imm8  | MI    | Valid       | N.E.        | Subtract imm8 from r/m8.                                           |
+| 81 /5 iw         | SUB r/m16, imm16 | MI    | Valid       | Valid       | Subtract imm16 from r/m16.                                         |
+| 81 /5 id         | SUB r/m32, imm32 | MI    | Valid       | Valid       | Subtract imm32 from r/m32.                                         |
+| REX.W + 81 /5 id | SUB r/m64, imm32 | MI    | Valid       | N.E.        | Subtract imm32 sign-extended to 64-bits from r/m64.                |
+| 83 /5 ib         | SUB r/m16, imm8  | MI    | Valid       | Valid       | Subtract sign-extended imm8 from r/m16.                            |
+| 83 /5 ib         | SUB r/m32, imm8  | MI    | Valid       | Valid       | Subtract sign-extended imm8 from r/m32.                            |
+| REX.W + 83 /5 ib | SUB r/m64, imm8  | MI    | Valid       | N.E.        | Subtract sign-extended imm8 from r/m64.                            |
+| 28 /r            | SUB r/m8, r8     | MR    | Valid       | Valid       | Subtract r8 from r/m8.                                             |
+| REX + 28 /r      | SUB r/m8*, r8*   | MR    | Valid       | N.E.        | Subtract r8 from r/m8.                                             |
+| 29 /r            | SUB r/m16, r16   | MR    | Valid       | Valid       | Subtract r16 from r/m16.                                           |
+| 29 /r            | SUB r/m32, r32   | MR    | Valid       | Valid       | Subtract r32 from r/m32.                                           |
+| REX.W + 29 /r    | SUB r/m64, r64   | MR    | Valid       | N.E.        | Subtract r64 from r/m64.                                           |
+| 2A /r            | SUB r8, r/m8     | RM    | Valid       | Valid       | Subtract r/m8 from r8.                                             |
+| REX + 2A /r      | SUB r8*, r/m8*   | RM    | Valid       | N.E.        | Subtract r/m8 from r8.                                             |
+| 2B /r            | SUB r16, r/m16   | RM    | Valid       | Valid       | Subtract r/m16 from r16.                                           |
+| 2B /r            | SUB r32, r/m32   | RM    | Valid       | Valid       | Subtract r/m32 from r32.                                           |
+| REX.W + 2B /r    | SUB r64, r/m64   | RM    | Valid       | N.E.        | Subtract r/m64 from r64.                                           |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
+
+The SUB instruction performs integer subtraction. It evaluates the result for both signed and unsigned integer operands and sets the OF and CF
+flags to indicate an overflow in the signed or unsigned result, respectively. The SF flag indicates the sign of the signed result.
+
+In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional
+registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this
+section for encoding data and limits.
diff --git a/xanual/syscall.md b/xanual/syscall.md
new file mode 100755 (executable)
index 0000000..c3020e9
--- /dev/null
@@ -0,0 +1,27 @@
+# SYSCALL — Fast System Call
+
+## Description
+
+SYSCALL invokes an OS system-call handler at privilege level 0. It does so by loading RIP from the IA32_LSTAR MSR (after saving the address of
+the instruction following SYSCALL into RCX). The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.
+
+## Instruction
+
+| Opcode | Assembly | Op/En | Modern Mode | Legacy Mode | Description                                                                          |
+|--------|----------|-------|-------------|-------------|--------------------------------------------------------------------------------------|
+| 0F 05  | SYSCALL  | NP    | Valid       | Invalid     | Fast call to privilege level 0 system procedures.                                    |
+
+## Information
+
+SYSCALL also saves RFLAGS into R11 and then masks RFLAGS using the IA32_FMASK MSR (MSR address C0000084H); specifically, the processor clears
+in RFLAGS every bit corresponding to a bit that is set in the IA32_FMASK MSR.
+
+SYSCALL loads the CS and SS selectors with values derived from bits 47:32 of the IA32_STAR MSR. However, the CS and SS descriptor caches are
+not loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See
+the Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those
+selector values correspond to the fixed values loaded into the descriptor caches; the SYSCALL instruction does not ensure this correspondence.
+
+The SYSCALL instruction does not save the stack pointer (RSP). If the OS system-call handler will change the stack pointer, it is the
+responsibility of software to save the previous value of the stack pointer. This might be done prior to executing SYSCALL, with software
+restoring the stack pointer with the instruction following SYSCALL (which will be executed after SYSRET). Alternatively, the OS system-call
+handler may save the stack pointer and restore it before executing SYSRET.
diff --git a/xanual/sysenter.md b/xanual/sysenter.md
new file mode 100755 (executable)
index 0000000..82d8347
--- /dev/null
@@ -0,0 +1,61 @@
+# SYSENTER — Fast System Call
+
+## Description
+
+Executes a fast call to a level 0 system procedure or routine. SYSENTER is a companion instruction to SYSEXIT. The instruction is optimized to
+provide the maximum performance for system calls from user code running at privilege level 3 to operating system or executive procedures
+running at privilege level 0.
+
+## Instruction
+
+| Opcode | Assembly | Op/En | Modern Mode | Legacy Mode | Description                                                                          |
+|--------|----------|-------|-------------|-------------|--------------------------------------------------------------------------------------|
+| 0F 34  | SYSENTER | NP    | Valid       | Valid       | Fast call to privilege level 0 system procedures.                                    |
+
+## Information
+
+When executed in IA-32e mode, the SYSENTER instruction transitions the logical processor to 64-bit mode; otherwise, the logical processor
+remains in protected mode.
+
+Prior to executing the SYSENTER instruction, software must specify the privilege level 0 code segment and code entry point, and the privilege
+level 0 stack segment and stack pointer by writing values to the following MSRs: - IA32_SYSENTER_CS (MSR address 174H) — The lower 16 bits of
+this MSR are the segment selector for the privilege level 0 code segment. This value is also used to determine the segment selector of the
+privilege level 0 stack segment (see the Operation section). This value cannot indicate a null selector.
+
+- IA32_SYSENTER_EIP (MSR address 176H) — The value of this MSR is loaded into RIP (thus, this value references the first instruction of the
+selected operating procedure or routine). In protected mode, only bits 31:0 are loaded.
+
+- IA32_SYSENTER_ESP (MSR address 175H) — The value of this MSR is loaded into RSP (thus, this value contains the stack pointer for the
+privilege level 0 stack). This value cannot represent a non-canonical address. In protected mode, only bits 31:0 are loaded.
+
+These MSRs can be read from and written to using RDMSR/WRMSR. The WRMSR instruction ensures that the IA32_SYSENTER_EIP and IA32_SYSENTER_ESP
+MSRs always contain canonical addresses.
+
+While SYSENTER loads the CS and SS selectors with values derived from the IA32_SYSENTER_CS MSR, the CS and SS descriptor caches are not loaded
+from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the
+Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those
+selector values correspond to the fixed values loaded into the descriptor caches; the SYSENTER instruction does not ensure this correspondence.
+The SYSENTER instruction can be invoked from all operating modes except real-address mode.
+
+The SYSENTER and SYSEXIT instructions are companion instructions, but they do not constitute a call/return pair. When executing a SYSENTER
+instruction, the processor does not save state information for the user code (e.g., the instruction pointer), and neither the SYSENTER nor the
+SYSEXIT instruction supports passing parameters on the stack.
+
+To use the SYSENTER and SYSEXIT instructions as companion instructions for transitions between privilege level 3 code and privilege level 0
+operating system procedures, the following conventions must be followed:
+
+- The segment descriptors for the privilege level 0 code and stack segments and for the privilege level 3 code and stack segments must be
+contiguous in a descriptor table. This convention allows the processor to compute the segment selectors from the value entered in the
+SYSENTER_CS_MSR MSR.
+
+- The fast system call "stub" routines executed by user code (typically in shared libraries or DLLs) must save the required return IP and
+processor state information if a return to the calling procedure is required. Likewise, the operating system or executive procedures called
+with SYSENTER instructions must have access to and use this saved return and state information when returning to the user code.
+
+The SYSENTER and SYSEXIT instructions were introduced into the IA-32 architecture in the Pentium II processor. The availability of these
+instructions on a processor is indicated with the SYSENTER/SYSEXIT present (SEP) feature flag returned to the EDX register by the CPUID
+instruction. An operating system that qualifies the SEP flag must also qualify the processor family and model to ensure that the
+SYSENTER/SYSEXIT instructions are actually present.
+
+When the CPUID instruction is executed on the Pentium Pro processor (model 1), the processor returns a the SEP flag as set, but does not
+support the SYSENTER/SYSEXIT instructions.
diff --git a/xanual/sysexit.md b/xanual/sysexit.md
new file mode 100755 (executable)
index 0000000..1261727
--- /dev/null
@@ -0,0 +1,46 @@
+# SYSEXIT — Return from Fast System Call
+
+## Description
+
+Executes a fast return to privilege level 3 user code. SYSEXIT is a companion instruction to the SYSENTER instruction. The instruction is
+optimized to provide the maximum performance for returns from system procedures executing at protections levels 0 to user procedures executing
+at protection level 3. It must be executed from code executing at privilege level 0.
+
+## Instruction
+
+| Opcode        | Assembly | Op/En | Modern Mode | Legacy Mode | Description                                                                   |
+|---------------|----------|-------|-------------|-------------|-------------------------------------------------------------------------------|
+| 0F 35         | SYSEXIT  | NP    | Valid       | Valid       | Fast return to privilege level 3 user code.                                   |
+| REX.W + 0F 35 | SYSEXIT  | NP    | Valid       | Valid       | Fast return to 64-bit mode privilege level 3 user code.                       |
+
+## Information
+
+With a 64-bit operand size, SYSEXIT remains in 64-bit mode; otherwise, it either enters compatibility mode (if the logical processor is in
+IA-32e mode) or remains in protected mode (if it is not).
+
+Prior to executing SYSEXIT, software must specify the privilege level 3 code segment and code entry point, and the privilege level 3 stack
+segment and stack pointer by writing values into the following MSR and general-purpose registers:
+
+- IA32_SYSENTER_CS (MSR address 174H) — Contains a 32-bit value that is used to determine the segment selectors for the privilege level 3 code
+and stack segments.
+
+- RDX — The canonical address in this register is loaded into RIP (thus, this value references the first instruction to be executed in the user
+code). If the return is not to 64-bit mode, only bits 31:0 are loaded.
+
+- ECX — The canonical address in this register is loaded into RSP (thus, this value contains the stack pointer for the privilege level 3
+stack). If the return is not to 64-bit mode, only bits 31:0 are loaded. The IA32_SYSENTER_CS MSR can be read from and written to using RDMSR
+and WRMSR.
+
+While SYSEXIT loads the CS and SS selectors with values derived from the IA32_SYSENTER_CS MSR, the CS and SS descriptor caches are not loaded
+from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the
+Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those
+selector values correspond to the fixed values loaded into the descriptor caches; the SYSEXIT instruction does not ensure this correspondence.
+The SYSEXIT instruction can be invoked from all operating modes except real-address mode and virtual-8086 mode.
+
+The SYSENTER and SYSEXIT instructions were introduced into the IA-32 architecture in the Pentium II processor. The availability of these
+instructions on a processor is indicated with the SYSENTER/SYSEXIT present (SEP) feature flag returned to the EDX register by the CPUID
+instruction. An operating system that qualifies the SEP flag must also qualify the processor family and model to ensure that the
+SYSENTER/SYSEXIT instructions are actually present.
+
+When the CPUID instruction is executed on the Pentium Pro processor (model 1), the processor returns a the SEP flag as set, but does not
+support the SYSENTER/SYSEXIT instructions.
diff --git a/xanual/sysret.md b/xanual/sysret.md
new file mode 100755 (executable)
index 0000000..251d7d7
--- /dev/null
@@ -0,0 +1,42 @@
+# SYSRET — Return from Fast System Call
+
+## Description
+
+SYSRET is a companion instruction to the SYSCALL instruction. It returns from an OS system-call handler to user code at privilege level 3. It
+does so by loading RIP from RCX and loading RFLAGS from R11.1 With a 64-bit operand size, SYSRET remains in 64-bit mode; otherwise, it enters
+compatibility mode and only the low 32 bits of the regis- ters are loaded.
+
+## Instruction
+
+| Opcode        | Assembly | Op/En | Modern Mode | Legacy Mode | Description                                                                   |
+|---------------|----------|-------|-------------|-------------|-------------------------------------------------------------------------------|
+| 0F 07         | SYSRET   | NP    | Valid       | Invalid     | Return to compatibility mode from fast system call.                           |
+| REX.W + 0F 07 | SYSRET   | NP    | Valid       | Invalid     | Return to 64-bit mode from fast system call.                                  |
+
+## Information
+
+SYSRET loads the CS and SS selectors with values derived from bits 63:48 of the IA32_STAR MSR. However, the CS and SS descriptor caches are not
+loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the
+Operation section for details. It is the respon- sibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those
+selector values corre- spond to the fixed values loaded into the descriptor caches; the SYSRET instruction does not ensure this correspondence.
+
+The SYSRET instruction does not modify the stack pointer (ESP or RSP). For that reason, it is necessary for software to switch to the user
+stack. The OS may load the user stack pointer (if it was saved after SYSCALL) before executing SYSRET; alternatively, user code may load the
+stack pointer (if it was saved before SYSCALL) after receiving control from SYSRET.
+
+If the OS loads the stack pointer before executing SYSRET, it must ensure that the handler of any interrupt or exception delivered between
+restoring the stack pointer and successful execution of SYSRET is not invoked with the user stack. It can do so using approaches such as the
+following:
+
+- External interrupts. The OS can prevent an external interrupt from being delivered by clearing EFLAGS.IF before loading the user stack
+pointer.
+
+- Nonmaskable interrupts (NMIs). The OS can ensure that the NMI handler is invoked with the correct stack by using the interrupt stack table
+(IST) mechanism for gate 2 (NMI) in the IDT .
+
+- General-protection exceptions (#GP). The SYSRET instruction generates #GP(0) if the value of RCX is not canonical. The OS can address this
+possibility using one or more of the following approaches:
+
+1) Confirming that the value of RCX is canonical before executing SYSRET.
+2) Using paging to ensure that the SYSCALL instruction will never save a non-canonical value into RCX.
+3) Using the IST mechanism for gate 13 (#GP) in the IDT.
diff --git a/xanual/template.md b/xanual/template.md
new file mode 100755 (executable)
index 0000000..9b7abf8
--- /dev/null
@@ -0,0 +1,15 @@
+#
+
+## Description
+
+
+
+## Instruction
+
+| Opcode | Assembly    | Op/En | Modern Mode | Legacy Mode | Description                                                                       |
+|--------|-------------|-------|-------------|-------------|-----------------------------------------------------------------------------------|
+
+
+## Information
+
+
diff --git a/xanual/xor.md b/xanual/xor.md
new file mode 100755 (executable)
index 0000000..81b28b9
--- /dev/null
@@ -0,0 +1,44 @@
+# XOR — Logical Exclusive Or
+
+## Description
+
+Performs a bitwise exclusive OR (XOR) operation on the destination (first) and source (second) operands and stores the result in the
+destination operand location. The source operand can be an immediate, a register, or a memory location; the destination operand can be a
+register or a memory location. However, two memory operands cannot be used in one instruction. Each bit of the result is 1 if the corresponding
+bits of the operands are different; each bit is 0 if the corresponding bits are the same.
+
+## Instruction
+
+| Opcode           | Assembly         | Op/En | Modern Mode | Legacy Mode | Description                                                        |
+|------------------|------------------|-------|-------------|-------------|--------------------------------------------------------------------|
+| 34 ib            | XOR AL, imm8     | I     | Valid       | Valid       | AL XOR imm8.                                                       |
+| 35 iw            | XOR AX, imm16    | I     | Valid       | Valid       | AX XOR imm16.                                                      |
+| 35 id            | XOR EAX, imm32   | I     | Valid       | Valid       | EAX XOR imm32.                                                     |
+| REX.W + 35 id    | XOR RAX, imm32   | I     | Valid       | N.E.        | RAX XOR imm32 (sign-extended).                                     |
+| 80 /6 ib         | XOR r/m8, imm8   | MI    | Valid       | Valid       | r/m8 XOR imm8.                                                     |
+| REX + 80 /6 ib   | XOR r/m8*, imm8  | MI    | Valid       | N.E.        | r/m8 XOR imm8.                                                     |
+| 81 /6 iw         | XOR r/m16, imm16 | MI    | Valid       | Valid       | r/m16 XOR imm16.                                                   |
+| 81 /6 id         | XOR r/m32, imm32 | MI    | Valid       | Valid       | r/m32 XOR imm32.                                                   |
+| REX.W + 81 /6 id | XOR r/m64, imm32 | MI    | Valid       | N.E.        | r/m64 XOR imm32 (sign-extended).                                   |
+| 83 /6 ib         | XOR r/m16, imm8  | MI    | Valid       | Valid       | r/m16 XOR imm8 (sign-extended).                                    |
+| 83 /6 ib         | XOR r/m32, imm8  | MI    | Valid       | Valid       | r/m32 XOR imm8 (sign-extended).                                    |
+| REX.W + 83 /6 ib | XOR r/m64, imm8  | MI    | Valid       | N.E.        | r/m64 XOR imm8 (sign-extended).                                    |
+| 30 /r            | XOR r/m8, r8     | MR    | Valid       | Valid       | r/m8 XOR r8.                                                       |
+| REX + 30 /r      | XOR r/m8*, r8*   | MR    | Valid       | N.E.        | r/m8 XOR r8.                                                       |
+| 31 /r            | XOR r/m16, r16   | MR    | Valid       | Valid       | r/m16 XOR r16.                                                     |
+| 31 /r            | XOR r/m32, r32   | MR    | Valid       | Valid       | r/m32 XOR r32.                                                     |
+| REX.W + 31 /r    | XOR r/m64, r64   | MR    | Valid       | N.E.        | r/m64 XOR r64.                                                     |
+| 32 /r            | XOR r8, r/m8     | RM    | Valid       | Valid       | r8 XOR r/m8.                                                       |
+| REX + 32 /r      | XOR r8*, r/m8*   | RM    | Valid       | N.E.        | r8 XOR r/m8.                                                       |
+| 33 /r            | XOR r16, r/m16   | RM    | Valid       | Valid       | r16 XOR r/m16.                                                     |
+| 33 /r            | XOR r32, r/m32   | RM    | Valid       | Valid       | r32 XOR r/m32.                                                     |
+| REX.W + 33 /r    | XOR r64, r/m64   | RM    | Valid       | N.E.        | r64 XOR r/m64.                                                     |
+
+- In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
+
+## Information
+
+This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
+
+In 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of
+REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.
diff --git a/xaptor b/xaptor
new file mode 100755 (executable)
index 0000000..68c322e
Binary files /dev/null and b/xaptor differ
diff --git a/xaptor.c b/xaptor.c
new file mode 100644 (file)
index 0000000..cf59554
--- /dev/null
+++ b/xaptor.c
@@ -0,0 +1,44 @@
+#define use_fatal_failure
+#define use_png_library
+#define use_raptor_renderer
+//~#define use_common_renderer
+//~#define use_opengl_renderer
+//~#define use_vulkan_renderer
+
+#include <xolatile/xtandard.h>
+#include <xolatile/xormat.h>
+#include <xolatile/xross.h>
+#include <xolatile/xui.h>
+
+int main (void) {
+       cross_structure * cross = cross_initialize (30, 3);
+       ui_structure    * ui    = ui_initialize    (cross);
+
+       cross_configure (cross, 640, 480, "Xaptor - File Manager");
+
+       while (cross->active == true) {
+               const uint offset = 48;
+
+               cross_synchronize (cross, 0x00000000);
+
+               ui_render_window (cross, ui, 0, 0, cross->window_width, cross->window_height);
+
+               ui_render_status (cross, ui, offset, offset, cross->window_width - 2 * offset, cross->window_height - 2 * offset);
+
+               cross_render_string (cross, "Xaptors are coming!", 0, 2 * offset, 2 * offset, 1.5f, 0x4488ccff);
+
+               cross_render_string (cross, format ("%i", cross->framerate),      0, 2 * offset, 3 * offset, 1.0f, 0x4488ccff);
+               cross_render_string (cross, format ("%i", cross->global_tick),    0, 2 * offset, 4 * offset, 1.0f, 0x4488ccff);
+               cross_render_string (cross, format ("%i", cross->gameplay_tick),  0, 2 * offset, 5 * offset, 1.0f, 0x4488ccff);
+               cross_render_string (cross, format ("%i", cross->animation_tick), 0, 2 * offset, 6 * offset, 1.0f, 0x4488ccff);
+               cross_render_string (cross, format ("%i", cross->cursor_x),       0, 2 * offset, 7 * offset, 1.0f, 0x4488ccff);
+               cross_render_string (cross, format ("%i", cross->cursor_y),       0, 2 * offset, 8 * offset, 1.0f, 0x4488ccff);
+
+               if (cross->signal [signal_q] == true) break;
+       }
+
+       cross = cross_deinitialize (cross);
+       ui    = ui_deinitialize    (ui);
+
+       return (log_success);
+}
diff --git a/xaptor.h b/xaptor.h
new file mode 100644 (file)
index 0000000..8567acf
--- /dev/null
+++ b/xaptor.h
@@ -0,0 +1,679 @@
+///                  _
+/// __  ____ _ _ __ | |_ ___  _ __
+/// \ \/ / _` | '_ \| __/ _ \| '__|
+///  >  < (_| | |_) | || (_) | |
+/// /_/\_\__,_| .__/ \__\___/|_|
+///           |_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xaptor - Carnivorous medium-to-large sized Xlib wrapper that has a hooked beak and large sharp talons.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+typedef struct {
+       Display     * display;
+       Window        window;
+       XVisualInfo   visual;
+       GC            context;
+       Pixmap        pixmap;
+       XImage      * image;
+       Atom          atom_close_button;
+       Atom          atom_transparency;
+
+       bool signal [signal_count];
+       bool cursor [cursor_count];
+       int  cursor_x;
+       int  cursor_y;
+
+       uint      gameplay_framerate;
+       uint      animation_framerate;
+       uint      window_width;
+       uint      window_height;
+       bool      active;
+       uint      framerate;
+       ulong     frame_time;
+       ulong     frame_begin;
+       ulong     frame_end;
+       uint    * framebuffer;
+       uint      global_tick;
+       uint      gameplay_tick;
+       uint      animation_tick;
+       uint      tab_width;
+       uint      sprite_count;
+       uint      font_count;
+       uint  * * sprite_data;
+       uint    * sprite_width;
+       uint    * sprite_height;
+       uint  * * font_index;
+       uint  * * font_width;
+       uint  * * font_height;
+       char    * font_begin;
+       char    * font_end;
+} raptor_structure;
+
+static raptor_structure * raptor_initialize (uint gameplay_framerate, uint animation_framerate) {
+       raptor_structure * raptor = allocate (sizeof (* raptor));
+
+       raptor->gameplay_framerate  = gameplay_framerate;
+       raptor->animation_framerate = animation_framerate;
+       raptor->tab_width           = 8;
+
+       return (raptor);
+}
+
+static raptor_structure * raptor_deinitialize (raptor_structure * raptor) {
+       for (uint index = 0; index < raptor->sprite_count; ++index) {
+               raptor->sprite_data [index] = deallocate (raptor->sprite_data [index]);
+       }
+
+       for (uint index = 0; index < raptor->font_count; ++index) {
+               raptor->font_index  [index] = deallocate (raptor->font_index  [index]);
+               raptor->font_width  [index] = deallocate (raptor->font_width  [index]);
+               raptor->font_height [index] = deallocate (raptor->font_height [index]);
+       }
+
+       raptor->font_index  = deallocate (raptor->font_index);
+       raptor->font_width  = deallocate (raptor->font_width);
+       raptor->font_height = deallocate (raptor->font_height);
+       raptor->font_begin  = deallocate (raptor->font_begin);
+       raptor->font_end    = deallocate (raptor->font_end);
+
+       raptor->sprite_data   = deallocate (raptor->sprite_data);
+       raptor->sprite_width  = deallocate (raptor->sprite_width);
+       raptor->sprite_height = deallocate (raptor->sprite_height);
+
+       if (raptor->framebuffer != null) {
+               raptor->framebuffer = deallocate (raptor->framebuffer);
+       }
+
+       XFreePixmap    (raptor->display, raptor->pixmap);
+       XFreeGC        (raptor->display, raptor->context);
+       XUnmapWindow   (raptor->display, raptor->window);
+       XDestroyWindow (raptor->display, raptor->window);
+
+       XCloseDisplay (raptor->display);
+
+       return (deallocate (raptor));
+}
+
+static uint raptor_sprite_raw_import (raptor_structure * raptor, uint * data, uint width, uint height) {
+       ++raptor->sprite_count;
+
+       raptor->sprite_data   = reallocate (raptor->sprite_data,   raptor->sprite_count * sizeof (* raptor->sprite_data));
+       raptor->sprite_width  = reallocate (raptor->sprite_width,  raptor->sprite_count * sizeof (* raptor->sprite_width));
+       raptor->sprite_height = reallocate (raptor->sprite_height, raptor->sprite_count * sizeof (* raptor->sprite_height));
+
+       raptor->sprite_data   [raptor->sprite_count - 1] = data;
+       raptor->sprite_width  [raptor->sprite_count - 1] = width;
+       raptor->sprite_height [raptor->sprite_count - 1] = height;
+
+       return (raptor->sprite_count - 1);
+}
+
+static uint raptor_font_raw_import (raptor_structure * raptor, uint * data, uint image_width, char begin, char end, uint separator_colour) {
+       uint   pointer = 0;
+       uint   width   = 0;
+       uint   height  = 0;
+       uint * buffer = null;
+
+       const uint current = raptor->font_count;
+
+       ++raptor->font_count;
+
+       raptor->font_index  = reallocate (raptor->font_index,  raptor->font_count * sizeof (* raptor->font_index));
+       raptor->font_width  = reallocate (raptor->font_width,  raptor->font_count * sizeof (* raptor->font_width));
+       raptor->font_height = reallocate (raptor->font_height, raptor->font_count * sizeof (* raptor->font_height));
+       raptor->font_begin  = reallocate (raptor->font_begin,  raptor->font_count * sizeof (* raptor->font_begin));
+       raptor->font_end    = reallocate (raptor->font_end,    raptor->font_count * sizeof (* raptor->font_end));
+
+       raptor->font_begin [current] = begin;
+       raptor->font_end   [current] = end;
+
+       raptor->font_index  [current] = allocate ((ulong) (end - begin + 1) * sizeof (* * raptor->font_index));
+       raptor->font_width  [current] = allocate ((ulong) (end - begin + 1) * sizeof (* * raptor->font_width));
+       raptor->font_height [current] = allocate ((ulong) (end - begin + 1) * sizeof (* * raptor->font_height));
+
+       for (char index = begin; index <= end; ++index) {
+               for (          ; data [pointer]                        == separator_colour; ++pointer);
+               for (width  = 0; data [pointer + width]                != separator_colour; ++width);
+               for (height = 0; data [pointer + height * image_width] != separator_colour; ++height);
+
+               buffer = allocate (width * height * sizeof (* buffer));
+
+               for (uint y = 0; y < height; ++y) {
+                       for (uint x = 0; x < width; ++x) {
+                               buffer [y * width + x] = data [pointer + (y * image_width) + x];
+                       }
+               }
+
+               raptor->font_index  [current] [index - begin] = raptor_sprite_raw_import (raptor, buffer, width, height);
+               raptor->font_width  [current] [index - begin] = width;
+               raptor->font_height [current] [index - begin] = height;
+
+               pointer += width;
+
+               for (; data [pointer] == separator_colour; ++pointer);
+
+               if (pointer % image_width == 2) {
+                       pointer += height * image_width;
+               }
+       }
+
+       return (current);
+}
+
+static uint raptor_sprite_import (raptor_structure * raptor, const char * path) {
+       uint   width  = 0;
+       uint   height = 0;
+       uint * data   = null;
+
+       data = format_image_import (path, & width, & height);
+
+       return (raptor_sprite_raw_import (raptor, data, width, height));
+}
+
+static uint raptor_font_import (raptor_structure * raptor, const char * path, char begin, char end, uint colour) {
+       uint   width  = 0;
+       uint   height = 0;
+       uint   result = 0;
+       uint * data   = null;
+
+       data = format_image_import (path, & width, & height);
+
+       result = raptor_font_raw_import (raptor, data, width, begin, end, colour);
+
+       data = deallocate (data);
+
+       return (result);
+}
+
+static uint raptor_sprite_width (const raptor_structure * raptor, uint sprite) {
+       return (raptor->sprite_width [sprite]);
+}
+
+static uint raptor_sprite_height (const raptor_structure * raptor, uint sprite) {
+       return (raptor->sprite_height [sprite]);
+}
+
+static uint raptor_character_width (raptor_structure * raptor, char character, uint font, float scale) {
+       if ((character < raptor->font_begin [font]) || (character > raptor->font_end [font])) {
+               return (0);
+       } else {
+               const uint index = raptor->font_index [font] [character - raptor->font_begin [font]];
+
+               return ((uint) (scale * (float) raptor->sprite_width [index]));
+       }
+}
+
+static uint raptor_character_height (raptor_structure * raptor, char character, uint font, float scale) {
+       if ((character < raptor->font_begin [font]) || (character > raptor->font_end [font])) {
+               return (0);
+       } else {
+               const uint index = raptor->font_index [font] [character - raptor->font_begin [font]];
+
+               return ((uint) (scale * (float) raptor->sprite_height [index]));
+       }
+}
+
+static uint raptor_string_width (raptor_structure * raptor, const char * string, uint font, float scale) {
+       uint width = 0;
+       uint match = 0;
+
+       if (string == null) {
+               return (0);
+       }
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               if (string [index] == '\t') {
+                       width += raptor->tab_width * raptor_character_width (raptor, ' ', font, scale);
+               } else if (string [index] == '\n') {
+                       match = maximum (width, match);
+                       width = 0;
+               } else {
+                       width += raptor_character_width (raptor, string [index], font, scale);
+               }
+       }
+
+       return (maximum (width, match));
+}
+
+static uint raptor_string_height (raptor_structure * raptor, const char * string, uint font, float scale) {
+       uint height = raptor_character_height (raptor, ' ', font, scale);
+
+       if ((string == null) || (string [0] == '\0')) {
+               return (0);
+       }
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               if (string [index] == '\n') {
+                       height += raptor_character_height (raptor, ' ', font, scale);
+               }
+       }
+
+       return (height);
+}
+
+static uint raptor_center_x (const raptor_structure * raptor, uint size) {
+       return ((raptor->window_width - size) / 2);
+}
+
+static uint raptor_center_y (const raptor_structure * raptor, uint size) {
+       return ((raptor->window_height - size) / 2);
+}
+
+static bool raptor_cursor_inside (const raptor_structure * raptor, int x, int y, uint width, uint height) {
+       return ((raptor->cursor_x > x)
+            && (raptor->cursor_y > y)
+            && (raptor->cursor_x < x + (int) width)
+            && (raptor->cursor_y < y + (int) height));
+}
+
+static bool raptor_cursor_left_click (const raptor_structure * raptor, int x, int y, uint width, uint height) {
+       if (raptor->cursor [cursor_left] == true) {
+               return (raptor_cursor_inside (raptor, x, y, width, height) == true);
+       }
+
+       return (false);
+}
+
+static bool raptor_cursor_right_click (const raptor_structure * raptor, int x, int y, uint width, uint height) {
+       if (raptor->cursor [cursor_right] == true) {
+               return (raptor_cursor_inside (raptor, x, y, width, height));
+       }
+
+       return (false);
+}
+
+static void raptor_configure (raptor_structure * raptor, uint window_width, uint window_height, const char * window_title) {
+       const ulong font_bitmap [2 * 95] = {
+               0x0000000000000000, 0x0000000000000000, 0x0000101010101010, 0x1000101000000000, 0x0024242400000000, 0x0000000000000000,
+               0x00002424247e2424, 0x7e24242400000000, 0x0010107c9290907c, 0x1212927c10100000, 0x0000649468081010, 0x202c524c00000000,
+               0x000018242418304a, 0x4444443a00000000, 0x0010101000000000, 0x0000000000000000, 0x0000081020202020, 0x2020100800000000,
+               0x0000201008080808, 0x0808102000000000, 0x000000000024187e, 0x1824000000000000, 0x000000000010107c, 0x1010000000000000,
+               0x0000000000000000, 0x0000101020000000, 0x000000000000007e, 0x0000000000000000, 0x0000000000000000, 0x0000101000000000,
+               0x0000040408081010, 0x2020404000000000, 0x00003c4242464a52, 0x6242423c00000000, 0x0000081828080808, 0x0808083e00000000,
+               0x00003c4242020408, 0x1020407e00000000, 0x00003c4242021c02, 0x0242423c00000000, 0x000002060a122242, 0x7e02020200000000,
+               0x00007e4040407c02, 0x0202423c00000000, 0x00001c2040407c42, 0x4242423c00000000, 0x00007e0202040408, 0x0810101000000000,
+               0x00003c4242423c42, 0x4242423c00000000, 0x00003c424242423e, 0x0202043800000000, 0x0000000000101000, 0x0000101000000000,
+               0x0000000000101000, 0x0000101020000000, 0x0000000408102040, 0x2010080400000000, 0x00000000007e0000, 0x7e00000000000000,
+               0x0000004020100804, 0x0810204000000000, 0x00003c4242420408, 0x0800080800000000, 0x00007c829ea2a2a2, 0xa69a807e00000000,
+               0x00003c424242427e, 0x4242424200000000, 0x00007c4242427c42, 0x4242427c00000000, 0x00003c4242404040, 0x4042423c00000000,
+               0x0000784442424242, 0x4242447800000000, 0x00007e4040407840, 0x4040407e00000000, 0x00007e4040407840, 0x4040404000000000,
+               0x00003c424240404e, 0x4242423c00000000, 0x0000424242427e42, 0x4242424200000000, 0x0000381010101010, 0x1010103800000000,
+               0x00000e0404040404, 0x0444443800000000, 0x0000424448506060, 0x5048444200000000, 0x0000404040404040, 0x4040407e00000000,
+               0x000082c6aa929282, 0x8282828200000000, 0x000042424262524a, 0x4642424200000000, 0x00003c4242424242, 0x4242423c00000000,
+               0x00007c424242427c, 0x4040404000000000, 0x00003c4242424242, 0x42424a3c02000000, 0x00007c424242427c, 0x5048444200000000,
+               0x00003c4240403c02, 0x0242423c00000000, 0x0000fe1010101010, 0x1010101000000000, 0x0000424242424242, 0x4242423c00000000,
+               0x0000424242424224, 0x2424181800000000, 0x0000828282828292, 0x92aac68200000000, 0x0000424224241818, 0x2424424200000000,
+               0x0000828244442810, 0x1010101000000000, 0x00007e0202040810, 0x2040407e00000000, 0x0000382020202020, 0x2020203800000000,
+               0x0000404020201010, 0x0808040400000000, 0x0000380808080808, 0x0808083800000000, 0x0000102844000000, 0x0000000000000000,
+               0x0000000000000000, 0x0000007e00000000, 0x1008000000000000, 0x0000000000000000, 0x00000000003c023e, 0x4242423e00000000,
+               0x00004040407c4242, 0x4242427c00000000, 0x00000000003c4240, 0x4040423c00000000, 0x00000202023e4242, 0x4242423e00000000,
+               0x00000000003c4242, 0x7e40403c00000000, 0x00000e10107c1010, 0x1010101000000000, 0x00000000003e4242, 0x4242423e02023c00,
+               0x00004040407c4242, 0x4242424200000000, 0x0000101000301010, 0x1010103800000000, 0x00000404000c0404, 0x0404040444443800,
+               0x0000404040424448, 0x7048444200000000, 0x0000301010101010, 0x1010103800000000, 0x0000000000fc9292, 0x9292929200000000,
+               0x00000000007c4242, 0x4242424200000000, 0x00000000003c4242, 0x4242423c00000000, 0x00000000007c4242, 0x4242427c40404000,
+               0x00000000003e4242, 0x4242423e02020200, 0x00000000005e6040, 0x4040404000000000, 0x00000000003e4040, 0x3c02027c00000000,
+               0x00001010107c1010, 0x1010100e00000000, 0x0000000000424242, 0x4242423e00000000, 0x0000000000424242, 0x2424181800000000,
+               0x0000000000828292, 0x9292927c00000000, 0x0000000000424224, 0x1824424200000000, 0x0000000000424242, 0x4242423e02023c00,
+               0x00000000007e0408, 0x1020407e00000000, 0x00000c1010102010, 0x1010100c00000000, 0x0000101010101010, 0x1010101000000000,
+               0x0000300808080408, 0x0808083000000000, 0x000000000062928c, 0x0000000000000000
+       };
+
+       XSetWindowAttributes window_attributes;
+
+       uint * dumb_buffer = allocate (256 * sizeof (* dumb_buffer));
+
+       for (uint index = 0; index < 256; ++index) {
+               dumb_buffer [index] = 0xffffffff;
+       }
+
+       ++raptor->font_count;
+
+       raptor->font_index  = reallocate (raptor->font_index,  raptor->font_count * sizeof (* raptor->font_index));
+       raptor->font_width  = reallocate (raptor->font_width,  raptor->font_count * sizeof (* raptor->font_width));
+       raptor->font_height = reallocate (raptor->font_height, raptor->font_count * sizeof (* raptor->font_height));
+       raptor->font_begin  = reallocate (raptor->font_begin,  raptor->font_count * sizeof (* raptor->font_begin));
+       raptor->font_end    = reallocate (raptor->font_end,    raptor->font_count * sizeof (* raptor->font_end));
+
+       raptor->font_begin [raptor->font_count - 1] = ' ';
+       raptor->font_end   [raptor->font_count - 1] = '~';
+
+       raptor->font_index  [raptor->font_count - 1] = allocate (95 * sizeof (* * raptor->font_index));
+       raptor->font_width  [raptor->font_count - 1] = allocate (95 * sizeof (* * raptor->font_width));
+       raptor->font_height [raptor->font_count - 1] = allocate (95 * sizeof (* * raptor->font_height));
+
+       for (uint index = 0; index < 95; ++index) {
+               uint * buffer = allocate (8 * 16 * sizeof (* buffer));
+
+               for (uint value = 0; value < 2; ++value) {
+                       for (uint bit = 64; bit > 0; --bit) {
+                               uint destination = ((value << 3) - ((bit - 1) >> 3) + 7) * 8 - ((bit - 1) & 7) + 7;
+                               uint source      = (font_bitmap [2 * index + value] >> (bit - 1)) & 1;
+
+                               buffer [destination] = (source) ? 0xffffffff : 0x00000000;
+                       }
+               }
+
+               raptor->font_index  [raptor->font_count - 1] [index] = raptor_sprite_raw_import (raptor, buffer, 8, 16);
+               raptor->font_width  [raptor->font_count - 1] [index] = 8;
+               raptor->font_height [raptor->font_count - 1] [index] = 16;
+       }
+
+       raptor_sprite_raw_import (raptor, dumb_buffer, 16, 16);
+
+       raptor->window_width  = window_width;
+       raptor->window_height = window_height;
+
+       raptor->display = XOpenDisplay (null);
+
+       int screen = DefaultScreen (raptor->display);
+
+       XMatchVisualInfo (raptor->display, screen, 32, TrueColor, & raptor->visual);
+
+       window_attributes.colormap = XCreateColormap (raptor->display, DefaultRootWindow (raptor->display), raptor->visual.visual, AllocNone);
+
+       window_attributes.border_pixel     = 0x00000000;
+       window_attributes.background_pixel = 0x00000000;
+
+       raptor->window = XCreateWindow (raptor->display, DefaultRootWindow (raptor->display), 0, 0, window_width, window_height, 0,
+                                        raptor->visual.depth, InputOutput, raptor->visual.visual, CWColormap | CWBorderPixel | CWBackPixel,
+                                        & window_attributes);
+
+       XStoreName (raptor->display, raptor->window, window_title);
+
+       XSelectInput (raptor->display, raptor->window, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask);
+
+       raptor->pixmap = XCreatePixmap (raptor->display, raptor->window, raptor->window_width, raptor->window_height, raptor->visual.depth);
+
+       raptor->context = XCreateGC (raptor->display, raptor->window, 0, null);
+
+       XSetForeground (raptor->display, raptor->context, BlackPixel (raptor->display, screen));
+
+       raptor->atom_close_button = XInternAtom (raptor->display, "WM_DELETE_WINDOW", false);
+
+       XSetWMProtocols (raptor->display, raptor->window, & raptor->atom_close_button, 1);
+
+       //~XGrabPointer(raptor->display, DefaultRootWindow (raptor->display), False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None,
+                    //~CurrentTime);
+
+       XMapWindow (raptor->display, raptor->window);
+
+       XFlush (raptor->display);
+
+       raptor->framebuffer = allocate (window_width * window_height * sizeof (* raptor->framebuffer));
+
+       raptor->active = true;
+
+       raptor->frame_begin = nano_time ();
+}
+
+static void raptor_render_base (raptor_structure * raptor, uint sprite, int x, int y, uint u, uint v, uint width, uint height, float scale_x,
+                                float scale_y, int flip_x, int flip_y, uint upper_left, uint upper_right, uint lower_left, uint lower_right) {
+       (void) scale_x;
+       (void) scale_y;
+       (void) flip_x;
+       (void) flip_y;
+       /// FIX TO INTERPOLATE ALL 4 COLOURS
+       //~(void) upper_left;
+       (void) upper_right;
+       (void) lower_left;
+       (void) lower_right;
+
+       uint interpolate_pixels (uint pixel, uint modifier) {
+               const uint r = (((pixel & 0xff000000) >> 24) * ((modifier & 0x000000ff) >>  0)) / 0xff;
+               const uint g = (((pixel & 0x00ff0000) >> 16) * ((modifier & 0x0000ff00) >>  8)) / 0xff;
+               const uint b = (((pixel & 0x0000ff00) >>  8) * ((modifier & 0x00ff0000) >> 16)) / 0xff;
+               const uint a = (((pixel & 0x000000ff) >>  0) * ((modifier & 0xff000000) >> 24)) / 0xff;
+
+               return ((r << 24) | (g << 16) | (b << 8) | a);
+       }
+
+       if ((x + (int) width < 0) || (y + (int) height < 0) || (x > (int) raptor->window_width) || (y > (int) raptor->window_height)) return;
+
+       for (uint vertical = 0; vertical < height; ++vertical) {
+               if (vertical + y >= raptor->window_height) break;
+               if (vertical + v >= raptor->sprite_height [sprite]) break;
+
+               for (uint horizontal = 0; horizontal < width; ++horizontal) {
+                       if (horizontal + x >= raptor->window_width) break;
+                       if (horizontal + u >= raptor->sprite_width [sprite]) break;
+
+                       const uint pixel = raptor->sprite_data [sprite] [(vertical + v) * raptor->sprite_width [sprite] + horizontal + u];
+                       const uint at    = (y + vertical) * raptor->window_width + (x + horizontal);
+
+                       raptor->framebuffer [at] = (((pixel & 0xff000000) >> 24) > 0x77)
+                                                ? interpolate_pixels (pixel, upper_left)
+                                                : raptor->framebuffer [at];
+               }
+       }
+}
+
+static void raptor_render_rectangle (raptor_structure * raptor, int x, int y, uint width, uint height, uint colour) {
+       raptor_render_base (raptor, raptor->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16, (float) height / 16, 0, 0, colour, colour,
+                           colour, colour);
+}
+
+static void raptor_render_sprite (raptor_structure * raptor, uint sprite, int x, int y) {
+       const uint width  = raptor->sprite_width  [sprite];
+       const uint height = raptor->sprite_height [sprite];
+
+       raptor_render_base (raptor, sprite, x, y, 0, 0, width, height, 1.0f, 1.0f, 0, 0, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+}
+
+static void raptor_render_sprite_scale (raptor_structure * raptor, uint sprite, int x, int y, float scale_x, float scale_y) {
+       const uint width  = raptor->sprite_width  [sprite];
+       const uint height = raptor->sprite_height [sprite];
+
+       raptor_render_base (raptor, sprite, x, y, 0, 0, width, height, scale_x, scale_y, 0, 0, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+                           0xffffffffu);
+}
+
+static void raptor_render_sprite_crop (raptor_structure * raptor, uint sprite, int x, int y, uint u, uint v, uint width, uint height) {
+       raptor_render_base (raptor, sprite, x, y, u, v, width, height, 1.0f, 1.0f, 0, 0, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+}
+
+static void raptor_render_sprite_colour (raptor_structure * raptor, uint sprite, uint colour, int x, int y) {
+       const uint width  = raptor->sprite_width  [sprite];
+       const uint height = raptor->sprite_height [sprite];
+
+       raptor_render_base (raptor, sprite, x, y, 0, 0, width, height, 1.0f, 1.0f, 0, 0, colour, colour, colour, colour);
+}
+
+static void raptor_render_sprite_crop_colour (raptor_structure * raptor, uint sprite, uint colour, int x, int y, uint u, uint v, uint width, uint height) {
+       raptor_render_base (raptor, sprite, x, y, u, v, width, height, 1.0f, 1.0f, 0, 0, colour, colour, colour, colour);
+}
+
+static void raptor_render_sprite_flip (raptor_structure * raptor, uint sprite, int x, int y, int flip_x, int flip_y) {
+       const uint width  = raptor->sprite_width  [sprite];
+       const uint height = raptor->sprite_height [sprite];
+
+       raptor_render_base (raptor, sprite, x, y, 0, 0, width, height, 1.0f, 1.0f, flip_x, flip_y, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+                           0xffffffffu);
+}
+
+static void raptor_render_sprite_animate (raptor_structure * raptor, uint sprite, int x, int y, uint frames, uint state, uint states) {
+       const uint width  = raptor->sprite_width  [sprite] / states;
+       const uint height = raptor->sprite_height [sprite] / frames;
+
+       const uint u = width  * (state                  % states);
+       const uint v = height * (raptor->animation_tick % frames);
+
+       raptor_render_sprite_crop (raptor, sprite, x, y, u, v, width, height);
+}
+
+static void raptor_render_character (raptor_structure * raptor, char character, uint font, int x, int y, float scale, uint colour) {
+       if ((character < raptor->font_begin [font]) || (character > raptor->font_end [font])) return;
+
+       const uint index  = raptor->font_index [font] [character - raptor->font_begin [font]];
+
+       const uint width  = raptor->sprite_width  [index];
+       const uint height = raptor->sprite_height [index];
+
+       raptor_render_base (raptor, index, x, y, 0, 0, width, height, scale, scale, 0, 0, colour, colour, colour, colour);
+}
+
+static void raptor_render_string (raptor_structure * raptor, const char * string, uint font, int x, int y, float scale, uint colour) {
+       int offset = x;
+
+       if (string == null) return;
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               if (string [index] == '\t') {
+                       x += raptor->tab_width * raptor_character_width (raptor, ' ', font, scale);
+                       continue;
+               } else if (string [index] == '\n') {
+                       x  = offset;
+                       y += raptor_character_height (raptor, ' ', font, scale);
+                       continue;
+               } else {
+                       raptor_render_character (raptor, string [index], font, x, y, scale, colour);
+
+                       x += raptor_character_width (raptor, string [index], font, scale);
+               }
+       }
+}
+
+static void raptor_render_framerate (raptor_structure * raptor, uint font, int x, int y, float scale, uint colour) {
+       raptor_render_string (raptor, number_to_string (raptor->framerate), font, x, y, scale, colour);
+}
+
+static void raptor_synchronize (raptor_structure * raptor, uint clear_colour) {
+       const uint signal_code [signal_count] = {
+               0,
+               38,     56,     54,     40,     26,     41,     42,     43,     31,     44,     45,     46,     58,     57,     32,     33,
+               24,     27,     39,     28,     30,     55,     25,     53,     29,     52,     19,     10,     11,     12,     13,     14,
+               15,     16,     17,     18,     9,      23,     36,     36,     61,     51,     47,     49,     65,     22,     60,     59,
+               48,     66,     20,     21,     34,     35,     37,     105,    50,     62,     64,     108,    67,     68,     69,     70,
+               71,     72,     73,     74,     75,     76,     95,     96,     111,    116,    113,    114,    77,     127,    118,    110,
+               112,    119,    115,    117,    86,     82,     63,     106,    104,    91,     90,     87,     88,     89,     83,     84,
+               85,     79,     80,     81
+       };
+
+       uint new_window_width  = raptor->window_width;
+       uint new_window_height = raptor->window_height;
+
+       XEvent event       = { 0 };
+       //~Window root_window = { 0 };
+
+       //~int  root_x = 0;
+       //~int  root_y = 0;
+       //~uint mask   = 0;
+
+       for (uint index = 0; index < cursor_count; ++index) {
+               raptor->cursor [index] = false;
+       }
+
+       for (uint index = 0; index < signal_count; ++index) {
+               raptor->signal [index] = false;
+       }
+
+       //~XQueryPointer (raptor->display, raptor->window, & root_window, & root_window, & root_x, & root_y, & root_x, & root_y, & mask);
+
+       XNextEvent (raptor->display, & event);
+
+       switch (event.type) {
+               case (Expose): {
+                       XFlush (raptor->display);
+               } break;
+               case (ClientMessage): {
+                       if ((Atom) event.xclient.data.l [0] == raptor->atom_close_button) {
+                               raptor->active = false;
+                               return;
+                       }
+               } break;
+               case (ConfigureNotify): {
+                       new_window_width  = event.xconfigure.width;
+                       new_window_height = event.xconfigure.height;
+               } break;
+               case (ButtonPress): {
+                       if (event.xbutton.button == Button1) raptor->cursor [cursor_left]   = true;
+                       if (event.xbutton.button == Button2) raptor->cursor [cursor_middle] = true;
+                       if (event.xbutton.button == Button3) raptor->cursor [cursor_right]  = true;
+                       raptor->cursor_x = event.xbutton.x;
+                       raptor->cursor_y = event.xbutton.y;
+               } break;
+               case (KeyPress): {
+                       for (uint index = 0; index < signal_count; ++index) {
+                               if (event.xkey.keycode == signal_code [index]) {
+                                       raptor->signal [index] = true;
+                               }
+                       }
+               } break;
+               default: {
+                       //~XFlush (raptor->display);
+                       return;
+               } break;
+       }
+
+       for (uint pixel = 0; pixel < raptor->window_width * raptor->window_height; ++pixel) {
+               uint r = (raptor->framebuffer [pixel] & 0x00ff0000) >> 16;
+               uint b = (raptor->framebuffer [pixel] & 0x000000ff) << 16;
+
+               raptor->framebuffer [pixel] = (raptor->framebuffer [pixel] & 0xff00ff00) | b | r;
+       }
+
+       raptor->image = XCreateImage (raptor->display, raptor->visual.visual, raptor->visual.depth, ZPixmap, 0, (char *) raptor->framebuffer,
+                                     raptor->window_width, raptor->window_height, 32, 0);
+
+       XPutImage (raptor->display, raptor->pixmap, raptor->context, raptor->image, 0, 0, 0, 0, raptor->window_width, raptor->window_height);
+
+       XCopyArea (raptor->display, raptor->pixmap, raptor->window, raptor->context, 0, 0, raptor->window_width, raptor->window_height, 0, 0);
+
+       XDestroyImage (raptor->image);
+
+       if ((new_window_width != raptor->window_width) || (new_window_height != raptor->window_height)) {
+               XFreePixmap (raptor->display, raptor->pixmap);
+
+               raptor->pixmap = XCreatePixmap (raptor->display, raptor->window, new_window_width, new_window_height, raptor->visual.depth);
+
+               raptor->window_width  = new_window_width;
+               raptor->window_height = new_window_height;
+       }
+
+       raptor->framebuffer = allocate (raptor->window_width * raptor->window_height * sizeof (* raptor->framebuffer));
+
+       clear_colour = colour_channel_reverse (clear_colour);
+
+       for (uint pixel = 0; pixel < raptor->window_width * raptor->window_height; ++pixel) {
+               raptor->framebuffer [pixel] = clear_colour;
+       }
+
+       raptor->frame_end = nano_time ();
+
+       raptor->frame_time = raptor->frame_end - raptor->frame_begin;
+
+       if (raptor->frame_time < 1000000000ul / raptor->gameplay_framerate) {
+               nano_wait (1000000000ul / raptor->gameplay_framerate - raptor->frame_time);
+       }
+
+       if (raptor->global_tick % raptor->gameplay_framerate == 0) {
+               raptor->framerate = (uint) (1000000000ul / raptor->frame_time);
+       }
+
+       ++raptor->global_tick;
+
+       raptor->global_tick = raptor->global_tick % (raptor->gameplay_framerate * raptor->animation_framerate);
+
+       raptor->gameplay_tick  = raptor->global_tick / raptor->animation_framerate;
+       raptor->animation_tick = raptor->global_tick / raptor->gameplay_framerate;
+
+       raptor->frame_begin = nano_time ();
+}
+
+////////////// MOVE ME PLEASE
+
+static void raptor_render_rectangle_vertical_gradient (raptor_structure * raptor, int x, int y, uint width, uint height, uint colour_up,
+                                                       uint colour_down) {
+       raptor_render_base (raptor, raptor->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16.0f, (float) height / 16.0f, 0, 0,
+                           colour_up, colour_up, colour_down, colour_down);
+}
diff --git a/xarbon.c b/xarbon.c
new file mode 100755 (executable)
index 0000000..a1bda6c
--- /dev/null
+++ b/xarbon.c
@@ -0,0 +1,274 @@
+///                 _
+/// __  ____ _ _ __| |__   ___  _ __
+/// \ \/ / _` | '__| '_ \ / _ \| '_ |
+///  >  < (_| | |  | |_) | (_) | | | |
+/// /_/\_\__,_|_|  |_.__/ \___/|_| |_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xarbon - Source code renderer to PNG image, very slow but self-contained, hardcoded font.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+#include <xolatile/xtandard.h>
+#include <xolatile/xyntax.h>
+#include <xolatile/xanguage.h>
+#include <xolatile/xormat/png.h>
+
+static const uint background    = 0xff181818;
+static const uint foreground    = 0xffcccccc;
+static const uint font_width    = 8;
+static const uint font_height   = 16;
+static const uint tab_width     = 8;
+static const uint render_border = 10;
+
+static uint * render_image  = null;
+static uint   render_width  = 0;
+static uint   render_height = 0;
+static uint   line_number   = 0;
+static uint   line_digits   = 0;
+
+static void conditionally_exit (language_structure * language, syntax_structure * syntax, bool terminate) {
+       syntax   = syntax_deinitialize   (syntax);
+       language = language_deinitialize (language);
+
+       if (terminate == true) {
+               exit (log_success);
+       }
+}
+
+static void print_common (void) {
+       print ("/B/4xarbon/-: /4Source code PNG renderer/-\n\n");
+       print ("\tAuthor:  /4Ognjen 'xolatile' Milan Robovic/-\n");
+       print ("\tLicense: /4GNU//GPLv3/-\n\n");
+}
+
+static void print_help (void) {
+       print_common ();
+
+       print ("Example usage:\n\n");
+       print ("\t/6$ cat file.ext | xarbon [flags]/- /0---/- You need to pass language flag in this case.\n");
+       print ("\t/6$ xarbon [flags] < file.ext/-     /0---/- You need to pass language flag in this case.\n");
+       print ("\t/6$ xarbon file.ext/-               /0---/- Language is automatically detected in this case.\n\n");
+       print ("Supported languages:\n\n");
+
+       for (uint index = 0; index < language_count; ++index) {
+               char align [32] = "";
+
+               print ("\t/B/4%s/- /4%s/- /0---/- %s syntax highlighting\n",
+                      language_short_option (index),
+                      string_align_left (string_copy (align, language_long_option (index)), 9, ' '),
+                      language_identifier (index));
+       }
+}
+
+static void print_version (void) {
+       print_common ();
+
+       print ("\tVersion: /40 (Zero)/-\n");
+}
+
+static uint fetch_width (const char * data) {
+       uint image_width = 0;
+       uint count       = 0;
+
+       do {
+               if (* data == '\t') {
+                       count += tab_width;
+               } else if (* data == '\n') {
+                       image_width = (++count > image_width) ? count : image_width;
+                       count = 0;
+               } else {
+                       ++count;
+               }
+       } while (* (++data) != '\0');
+
+       return (image_width - 1);
+}
+
+static uint fetch_height (const char * data) {
+       uint image_height = 0;
+       uint count        = 0;
+
+       do {
+               if (* data == '\n') {
+                       ++image_height;
+               }
+       } while (* (++data) != '\0');
+
+       count = image_height + 1;
+
+       do {
+               ++line_digits;
+
+               count /= 10;
+       } while (count > 0);
+
+       return (image_height + 1);
+}
+
+static void render_character (char character, uint * x, uint * y, uint colour) {
+       const ulong glyphmap [192] = {
+               0x0000000000000000, 0x0000000000000000, 0x0000101010101010, 0x1000101000000000, 0x0024242400000000, 0x0000000000000000,
+               0x00002424247e2424, 0x7e24242400000000, 0x0010107c9290907c, 0x1212927c10100000, 0x0000649468081010, 0x202c524c00000000,
+               0x000018242418304a, 0x4444443a00000000, 0x0010101000000000, 0x0000000000000000, 0x0000081020202020, 0x2020100800000000,
+               0x0000201008080808, 0x0808102000000000, 0x000000000024187e, 0x1824000000000000, 0x000000000010107c, 0x1010000000000000,
+               0x0000000000000000, 0x0000101020000000, 0x000000000000007e, 0x0000000000000000, 0x0000000000000000, 0x0000101000000000,
+               0x0000040408081010, 0x2020404000000000, 0x00003c4242464a52, 0x6242423c00000000, 0x0000081828080808, 0x0808083e00000000,
+               0x00003c4242020408, 0x1020407e00000000, 0x00003c4242021c02, 0x0242423c00000000, 0x000002060a122242, 0x7e02020200000000,
+               0x00007e4040407c02, 0x0202423c00000000, 0x00001c2040407c42, 0x4242423c00000000, 0x00007e0202040408, 0x0810101000000000,
+               0x00003c4242423c42, 0x4242423c00000000, 0x00003c424242423e, 0x0202043800000000, 0x0000000000101000, 0x0000101000000000,
+               0x0000000000101000, 0x0000101020000000, 0x0000000408102040, 0x2010080400000000, 0x00000000007e0000, 0x7e00000000000000,
+               0x0000004020100804, 0x0810204000000000, 0x00003c4242420408, 0x0800080800000000, 0x00007c829ea2a2a2, 0xa69a807e00000000,
+               0x00003c424242427e, 0x4242424200000000, 0x00007c4242427c42, 0x4242427c00000000, 0x00003c4242404040, 0x4042423c00000000,
+               0x0000784442424242, 0x4242447800000000, 0x00007e4040407840, 0x4040407e00000000, 0x00007e4040407840, 0x4040404000000000,
+               0x00003c424240404e, 0x4242423c00000000, 0x0000424242427e42, 0x4242424200000000, 0x0000381010101010, 0x1010103800000000,
+               0x00000e0404040404, 0x0444443800000000, 0x0000424448506060, 0x5048444200000000, 0x0000404040404040, 0x4040407e00000000,
+               0x000082c6aa929282, 0x8282828200000000, 0x000042424262524a, 0x4642424200000000, 0x00003c4242424242, 0x4242423c00000000,
+               0x00007c424242427c, 0x4040404000000000, 0x00003c4242424242, 0x42424a3c02000000, 0x00007c424242427c, 0x5048444200000000,
+               0x00003c4240403c02, 0x0242423c00000000, 0x0000fe1010101010, 0x1010101000000000, 0x0000424242424242, 0x4242423c00000000,
+               0x0000424242424224, 0x2424181800000000, 0x0000828282828292, 0x92aac68200000000, 0x0000424224241818, 0x2424424200000000,
+               0x0000828244442810, 0x1010101000000000, 0x00007e0202040810, 0x2040407e00000000, 0x0000382020202020, 0x2020203800000000,
+               0x0000404020201010, 0x0808040400000000, 0x0000380808080808, 0x0808083800000000, 0x0000102844000000, 0x0000000000000000,
+               0x0000000000000000, 0x0000007e00000000, 0x1008000000000000, 0x0000000000000000, 0x00000000003c023e, 0x4242423e00000000,
+               0x00004040407c4242, 0x4242427c00000000, 0x00000000003c4240, 0x4040423c00000000, 0x00000202023e4242, 0x4242423e00000000,
+               0x00000000003c4242, 0x7e40403c00000000, 0x00000e10107c1010, 0x1010101000000000, 0x00000000003e4242, 0x4242423e02023c00,
+               0x00004040407c4242, 0x4242424200000000, 0x0000101000301010, 0x1010103800000000, 0x00000404000c0404, 0x0404040444443800,
+               0x0000404040424448, 0x7048444200000000, 0x0000301010101010, 0x1010103800000000, 0x0000000000fc9292, 0x9292929200000000,
+               0x00000000007c4242, 0x4242424200000000, 0x00000000003c4242, 0x4242423c00000000, 0x00000000007c4242, 0x4242427c40404000,
+               0x00000000003e4242, 0x4242423e02020200, 0x00000000005e6040, 0x4040404000000000, 0x00000000003e4040, 0x3c02027c00000000,
+               0x00001010107c1010, 0x1010100e00000000, 0x0000000000424242, 0x4242423e00000000, 0x0000000000424242, 0x2424181800000000,
+               0x0000000000828292, 0x9292927c00000000, 0x0000000000424224, 0x1824424200000000, 0x0000000000424242, 0x4242423e02023c00,
+               0x00000000007e0408, 0x1020407e00000000, 0x00000c1010102010, 0x1010100c00000000, 0x0000101010101010, 0x1010101000000000,
+               0x0000300808080408, 0x0808083000000000, 0x000000000062928c, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
+       };
+
+       for (ulong index = 0; index < 2; ++index) {
+               for (ulong bit = 64; bit > 0; --bit) {
+                       ulong destination = (* y + (index << 3) - ((bit - 1) >> 3) + 7) * render_width + (* x - ((bit - 1) & 7) + 7);
+                       ulong source      = (glyphmap [2 * (ulong) (character - ' ') + index] >> (bit - 1)) & 1;
+
+                       render_image [destination] = (source) ? colour : background;
+               }
+       }
+
+       * x += font_width;
+}
+
+static void render_string (char * string, uint length, uint * x, uint * y, uint colour) {
+       for (uint offset = 0; offset < length; ++offset) {
+               if (string [offset] == '\t') {
+                       * x += font_width * tab_width;
+               } else if (string [offset] == '\n') {
+                       * y += font_height;
+                       * x  = render_border;
+
+                       render_string (format_to_string ((int) ++line_number, false, 10, (int) line_digits, ' '), line_digits, x, y, foreground);
+
+                       * x += font_width;
+               } else {
+                       render_character (string [offset], x, y, colour);
+               }
+       }
+}
+
+int main (int argc, char * * argv) {
+       uint   select = language_count;
+       uint   offset = 0;
+       uint   length = 0;
+       uint   x      = render_border;
+       uint   y      = render_border;
+       char * buffer = null;
+       char * dump   = null;
+
+       syntax_structure   * syntax   = syntax_initialize   (666);
+       language_structure * language = language_initialize (true);
+
+       for (int argument = 1; argument < argc; ++argument) {
+               if (argument_compare (argv [argument], "-h", "--help") == true) {
+                       print_help         ();
+                       conditionally_exit (language, syntax, true);
+               } else if (argument_compare (argv [argument], "-v", "--version") == true) {
+                       print_version      ();
+                       conditionally_exit (language, syntax, true);
+               } else if (argument_compare (argv [argument], "-o", "--output") == true) {
+                       if (argument + 1 >= argc) {
+                               print ("/f Expected output file name: /1%s/-\n", argv [argument]);
+                               conditionally_exit (language, syntax, true);
+                       }
+                       ++argument;
+                       dump = string_duplicate (argv [argument]);
+                       continue;
+               }
+
+               for (uint index = 0; index < language_count; ++index) {
+                       if (argument_compare (argv [argument], language_short_option (index), language_long_option (index)) == true) {
+                               (* (language_highlighter (index))) (language, syntax);
+                               select = index;
+                               break;
+                       }
+               }
+
+               if (file_exists (argv [argument]) == true) {
+                       if (select == language_count) {
+                               select = (uint) file_type (argv [argument]);
+                       }
+                       if (buffer == null) {
+                               buffer = file_import (argv [argument]);
+                       } continue;
+               } else {
+                       print ("/f Unrecognized command line argument: /1%s/-\n", argv [argument]);
+                       conditionally_exit (language, syntax, true);
+               }
+       }
+
+       if (dump == null) {
+               dump = string_duplicate ("xarbon.png");
+       }
+
+       if (select == language_count) {
+               select = language_common;
+       }
+
+       if (buffer == null) {
+               buffer = record ();
+       }
+
+       language_conditionally_select (language, syntax, select);
+
+       render_width  = fetch_width  (buffer) * font_width  + 2 * render_border;
+       render_height = fetch_height (buffer) * font_height + 2 * render_border;
+
+       render_width += (line_digits + 1) * font_width;
+
+       render_image = allocate (render_width * render_height * sizeof (* render_image));
+
+       for (offset = 0; offset < render_width * render_height; ++offset) {
+               render_image [offset] = background;
+       }
+
+       render_string (format_to_string ((int) ++line_number, false, 10, (int) line_digits, ' '), line_digits, & x, & y, foreground);
+
+       x += font_width;
+
+       for (offset = 0; buffer [offset] != '\0'; offset += length) {
+               select = syntax_select (syntax, & buffer [offset], & length);
+
+               render_string (& buffer [offset], length, & x, & y, (select >= syntax->count) ? background : (uint) syntax->colour [select]);
+       }
+
+       png_image_export (dump, render_image, render_width, render_height);
+
+       conditionally_exit (language, syntax, false);
+
+       render_image = deallocate (render_image);
+       buffer       = deallocate (buffer);
+       dump         = deallocate (dump);
+
+       return (log_success);
+}
diff --git a/xarticle.h b/xarticle.h
new file mode 100644 (file)
index 0000000..6c0f7bd
--- /dev/null
@@ -0,0 +1,170 @@
+///                 _   _      _
+/// __  ____ _ _ __| |_(_) ___| | ___
+/// \ \/ / _` | '__| __| |/ __| |/ _ \
+///  >  < (_| | |  | |_| | (__| |  __/
+/// /_/\_\__,_|_|   \__|_|\___|_|\___|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xarticle - Forgiving, kind and nice general static 3D particle system.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+typedef struct {
+       uint         count;
+       uint         limit;
+       uint       * sprite;
+       float      * life;
+       uint       * colour_in;
+       uint       * colour_out;
+       vector_3 * * position;
+       vector_3 * * target;
+       vector_3 * * speed;
+} particle_structure;
+
+static particle_structure * particle_initialize (uint limit) {
+       particle_structure * particle = allocate (sizeof (* particle));
+
+       particle->limit = limit;
+
+       particle->sprite     = allocate (limit * sizeof (* particle->sprite));
+       particle->life       = allocate (limit * sizeof (* particle->life));
+       particle->colour_in  = allocate (limit * sizeof (* particle->colour_in));
+       particle->colour_out = allocate (limit * sizeof (* particle->colour_out));
+       particle->position   = allocate (limit * sizeof (* particle->position));
+       particle->target     = allocate (limit * sizeof (* particle->target));
+       particle->speed      = allocate (limit * sizeof (* particle->speed));
+
+       for (uint index = 0; index < limit; ++index) {
+               particle->life [index] = 0.0f;
+
+               particle->position [index] = allocate (sizeof (* * particle->position));
+               particle->target   [index] = allocate (sizeof (* * particle->target));
+               particle->speed    [index] = allocate (sizeof (* * particle->speed));
+
+               vector_3_nullify (particle->position [index]);
+               vector_3_nullify (particle->target   [index]);
+               vector_3_nullify (particle->speed    [index]);
+       }
+
+       return (particle);
+}
+
+static particle_structure * particle_deinitialize (particle_structure * particle) {
+       for (uint index = 0; index < particle->count; ++index) {
+               particle->position [index] = deallocate (particle->position [index]);
+               particle->target   [index] = deallocate (particle->target   [index]);
+               particle->speed    [index] = deallocate (particle->speed    [index]);
+       }
+
+       particle->sprite     = deallocate (particle->sprite);
+       particle->life       = deallocate (particle->life);
+       particle->colour_in  = deallocate (particle->colour_in);
+       particle->colour_out = deallocate (particle->colour_out);
+       particle->position   = deallocate (particle->position);
+       particle->target     = deallocate (particle->target);
+       particle->speed      = deallocate (particle->speed);
+
+       return (deallocate (particle));
+}
+
+static void particle_append (particle_structure * particle, uint sprite, float life, uint colour_in, uint colour_out, const vector_3 * position,
+                             const vector_3 * target, const vector_3 * speed) {
+       if (particle->count + 1 >= particle->limit) return;
+
+       ++particle->count;
+
+       uint current = particle->count - 1;
+
+       particle->sprite     [current] = sprite;
+       particle->life       [current] = life;
+       particle->colour_in  [current] = colour_in;
+       particle->colour_out [current] = colour_out;
+
+       vector_3_copy (particle->position [current], position);
+       vector_3_copy (particle->target   [current], target);
+       vector_3_copy (particle->speed    [current], speed);
+}
+
+static void particle_switch (particle_structure * particle, uint this, uint with) {
+       uint_exchange     (& particle->sprite     [this], & particle->sprite     [with]);
+       float_exchange    (& particle->life       [this], & particle->life       [with]);
+       uint_exchange     (& particle->colour_in  [this], & particle->colour_in  [with]);
+       uint_exchange     (& particle->colour_out [this], & particle->colour_out [with]);
+       vector_3_exchange (  particle->position   [this],   particle->position   [with]);
+       vector_3_exchange (  particle->target     [this],   particle->target     [with]);
+       vector_3_exchange (  particle->speed      [this],   particle->speed      [with]);
+}
+
+static void particle_remove (particle_structure * particle, uint index) {
+       if (index >= particle->count) return;
+
+       particle_switch (particle, index, particle->count - 1);
+
+       --particle->count;
+}
+
+static void particle_effect_splash (particle_structure * particle, uint sprite, float life, uint colour_in, uint colour_out,
+                                    vector_3 * position, uint ray_count, float ray_force, float ray_error) {
+       for (uint ray = 0; ray < ray_count; ++ray) {
+               vector_3 target = {
+                       //~position->x + frandomize (- ray_force, + ray_force),
+                       //~position->y + frandomize (- ray_force, + ray_force),
+                       //~position->z + frandomize (- ray_force, + ray_force) + frandomize (- ray_error, + ray_error)
+                       //~frandomize (- ray_force, + ray_force),
+                       //~frandomize (- ray_force, + ray_force),
+                       //~frandomize (- ray_force, + ray_force)
+                        0.0f, 0.0f, 0.0f
+               };
+
+               vector_3 speed = {
+                       frandomize (- ray_force, + ray_force),
+                       frandomize (- ray_force, + ray_force),
+                       frandomize (- ray_force, + ray_force)
+               };
+
+               life += frandomize (- 1.0f, + 1.0f);
+
+               particle_append (particle, sprite, life, colour_in, colour_out, position, & target, & speed);
+       }
+}
+
+static void particle_effect_evaporate (particle_structure * particle, uint sprite, float life, uint colour_in, uint colour_out,
+                                       vector_3 * position, uint ray_count, float ray_force, float ray_error) {
+       for (uint ray = 0; ray < ray_count; ++ray) {
+               vector_3 target = {
+                       frandomize (0.0f, + ray_force / 6.0f),
+                       frandomize (0.0f, + ray_force / 1.0f),
+                       frandomize (0.0f, + ray_force / 6.0f),
+               };
+
+               vector_3 speed = {
+                       frandomize (- ray_force, + ray_force),
+                       frandomize (- ray_force, + ray_force),
+                       frandomize (- ray_force, + ray_force)
+               };
+
+               life += frandomize (- 1.0f, + 1.0f);
+
+               particle_append (particle, sprite, life, colour_in, colour_out, position, & target, & speed);
+       }
+}
+
+static void particle_synchronize (particle_structure * particle, uint framerate) {
+       for (uint index = 0; index < particle->count; ++index) {
+               particle->life [index] -= 1.0f / (float) framerate;
+
+               if (particle->life [index] < 0.0f) {
+                       particle_remove (particle, index);
+               }
+
+               vector_3_add (particle->position [index], particle->speed  [index]);
+               vector_3_add (particle->speed    [index], particle->target [index]);
+               //~vector_3_add (particle->position [index], particle->target [index]);
+       }
+}
diff --git a/xatrix.h b/xatrix.h
new file mode 100644 (file)
index 0000000..b0d8c8a
--- /dev/null
+++ b/xatrix.h
@@ -0,0 +1,510 @@
+///            _        _
+/// __  ____ _| |_ _ __(_)_  __
+/// \ \/ / _` | __| '__| \ \/ /
+///  >  < (_| | |_| |  | |>  <
+/// /_/\_\__,_|\__|_|  |_/_/\_\
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xatrix - Very dumb and slow matrix library, mathematical matrix, because I don't like other people ideas...
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+typedef float matrix_2 [2] [2];
+typedef float matrix_3 [3] [3];
+typedef float matrix_4 [4] [4];
+
+static matrix_2 * matrix_2_assign (matrix_2 * destination,
+                                   float m00, float m01,
+                                   float m10, float m11) {
+       destination [0] [0] = m00;
+       destination [0] [1] = m01;
+       destination [1] [0] = m10;
+       destination [1] [1] = m11;
+
+       return (destination);
+}
+
+static matrix_3 * matrix_3_assign (matrix_3 * destination,
+                                   float m00, float m01, float m02,
+                                   float m10, float m11, float m12,
+                                   float m20, float m21, float m22) {
+       destination [0] [0] = m00;
+       destination [0] [1] = m01;
+       destination [0] [2] = m02;
+       destination [1] [0] = m10;
+       destination [1] [1] = m11;
+       destination [1] [2] = m12;
+       destination [2] [0] = m20;
+       destination [2] [1] = m21;
+       destination [2] [2] = m22;
+
+       return (destination);
+}
+
+static matrix_4 * matrix_4_assign (matrix_4 * destination,
+                                   float m00, float m01, float m02, float m03,
+                                   float m10, float m11, float m12, float m13,
+                                   float m20, float m21, float m22, float m23,
+                                   float m30, float m31, float m32, float m33) {
+       destination [0] [0] = m00;
+       destination [0] [1] = m01;
+       destination [0] [2] = m02;
+       destination [0] [3] = m03;
+       destination [1] [0] = m10;
+       destination [1] [1] = m11;
+       destination [1] [2] = m12;
+       destination [1] [3] = m13;
+       destination [2] [0] = m20;
+       destination [2] [1] = m21;
+       destination [2] [2] = m22;
+       destination [2] [3] = m23;
+       destination [3] [0] = m30;
+       destination [3] [1] = m31;
+       destination [3] [2] = m32;
+       destination [3] [3] = m33;
+
+       return (destination);
+}
+
+static matrix_2 * matrix_2_nullify (matrix_2 * destination) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = 0; column < 2; ++column) {
+                       destination [row] [column] = 0.0f;
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_3 * matrix_3_nullify (matrix_3 * destination) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       destination [row] [column] = 0.0f;
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_4 * matrix_4_nullify (matrix_4 * destination) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       destination [row] [column] = 0.0f;
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_2 * matrix_2_identity (matrix_2 * destination) {
+       destination = matrix_2_nullify (destination);
+
+       for (uint index = 0; index < 2; ++index) {
+               destination [index] [index] = 1.0f;
+       }
+
+       return (destination);
+}
+
+static matrix_3 * matrix_3_identity (matrix_3 * destination) {
+       destination = matrix_3_nullify (destination);
+
+       for (uint index = 0; index < 3; ++index) {
+               destination [index] [index] = 1.0f;
+       }
+
+       return (destination);
+}
+
+static matrix_4 * matrix_4_identity (matrix_4 * destination) {
+       destination = matrix_4_nullify (destination);
+
+       for (uint index = 0; index < 4; ++index) {
+               destination [index] [index] = 1.0f;
+       }
+
+       return (destination);
+}
+
+static float matrix_2_determinant (const matrix_2 * matrix) {
+       const float a = matrix [0] [0] * matrix [1] [1];
+       const float b = matrix [0] [1] * matrix [1] [0];
+
+       return (a - b);
+}
+
+static float matrix_3_determinant (const matrix_3 * matrix) {
+       const matrix_2 matrix_a = { { matrix [1] [1], matrix [1] [2] },
+                                   { matrix [2] [1], matrix [2] [2] } };
+       const matrix_2 matrix_b = { { matrix [1] [0], matrix [1] [2] },
+                                   { matrix [2] [0], matrix [2] [2] } };
+       const matrix_2 matrix_c = { { matrix [1] [0], matrix [1] [1] },
+                                   { matrix [2] [0], matrix [2] [1] } };
+
+       const float a = matrix [0] [0] * matrix_2_determinant (& matrix_a);
+       const float b = matrix [0] [1] * matrix_2_determinant (& matrix_b);
+       const float c = matrix [0] [2] * matrix_2_determinant (& matrix_c);
+
+       return (a - b + c);
+}
+
+static float matrix_4_determinant (const matrix_4 * matrix) {
+       const matrix_3 matrix_a = { { matrix [1] [1], matrix [1] [2], matrix [1] [3] },
+                                   { matrix [2] [1], matrix [2] [2], matrix [2] [3] },
+                                   { matrix [3] [1], matrix [3] [2], matrix [3] [3] } };
+       const matrix_3 matrix_b = { { matrix [1] [0], matrix [1] [2], matrix [1] [3] },
+                                   { matrix [2] [0], matrix [2] [2], matrix [2] [3] },
+                                   { matrix [3] [0], matrix [3] [2], matrix [3] [3] } };
+       const matrix_3 matrix_c = { { matrix [1] [0], matrix [1] [1], matrix [1] [3] },
+                                   { matrix [2] [0], matrix [2] [1], matrix [2] [3] },
+                                   { matrix [3] [0], matrix [3] [1], matrix [3] [3] } };
+       const matrix_3 matrix_d = { { matrix [1] [0], matrix [1] [1], matrix [1] [2] },
+                                   { matrix [2] [0], matrix [2] [1], matrix [2] [2] },
+                                   { matrix [3] [0], matrix [3] [1], matrix [3] [2] } };
+
+       const float a = matrix [0] [0] * matrix_3_determinant (& matrix_a);
+       const float b = matrix [0] [1] * matrix_3_determinant (& matrix_b);
+       const float c = matrix [0] [2] * matrix_3_determinant (& matrix_c);
+       const float d = matrix [0] [3] * matrix_3_determinant (& matrix_d);
+
+       return (a - b + c - d);
+}
+
+static matrix_2 * matrix_2_copy (matrix_2 * destination, const matrix_2 * source) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = 0; column < 2; ++column) {
+                       destination [row] [column] = source [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_3 * matrix_3_copy (matrix_3 * destination, const matrix_3 * source) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       destination [row] [column] = source [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_4 * matrix_4_copy (matrix_4 * destination, const matrix_4 * source) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       destination [row] [column] = source [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_2 * matrix_2_scale (matrix_2 * destination, float scale) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = 0; column < 2; ++column) {
+                       destination [row] [column] *= scale;
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_3 * matrix_3_scale (matrix_3 * destination, float scale) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       destination [row] [column] *= scale;
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_4 * matrix_4_scale (matrix_4 * destination, float scale) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       destination [row] [column] *= scale;
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_2 * matrix_2_scale_to (matrix_2 * destination, const matrix_2 * source, float scale) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = 0; column < 2; ++column) {
+                       destination [row] [column] = source [row] [column] * scale;
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_3 * matrix_3_scale_to (matrix_3 * destination, const matrix_3 * source, float scale) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       destination [row] [column] = source [row] [column] * scale;
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_4 * matrix_4_scale_to (matrix_4 * destination, const matrix_4 * source, float scale) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       destination [row] [column] = source [row] [column] * scale;
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_2 * matrix_2_add (matrix_2 * destination, const matrix_2 * source) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = 0; column < 2; ++column) {
+                       destination [row] [column] += source [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_3 * matrix_3_add (matrix_3 * destination, const matrix_3 * source) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       destination [row] [column] += source [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_4 * matrix_4_add (matrix_4 * destination, const matrix_4 * source) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       destination [row] [column] += source [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_2 * matrix_2_add_to (matrix_2 * destination, const matrix_2 * matrix_a, const matrix_2 * matrix_b) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = 0; column < 2; ++column) {
+                       destination [row] [column] = matrix_a [row] [column] + matrix_b [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_3 * matrix_3_add_to (matrix_3 * destination, const matrix_3 * matrix_a, const matrix_3 * matrix_b) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       destination [row] [column] = matrix_a [row] [column] + matrix_b [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_4 * matrix_4_add_to (matrix_4 * destination, const matrix_4 * matrix_a, const matrix_4 * matrix_b) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       destination [row] [column] = matrix_a [row] [column] + matrix_b [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_2 * matrix_2_subtract (matrix_2 * destination, const matrix_2 * source) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = 0; column < 2; ++column) {
+                       destination [row] [column] -= source [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_3 * matrix_3_subtract (matrix_3 * destination, const matrix_3 * source) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       destination [row] [column] -= source [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_4 * matrix_4_subtract (matrix_4 * destination, const matrix_4 * source) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       destination [row] [column] -= source [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_2 * matrix_2_subtract_to (matrix_2 * destination, const matrix_2 * matrix_a, const matrix_2 * matrix_b) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = 0; column < 2; ++column) {
+                       destination [row] [column] = matrix_a [row] [column] - matrix_b [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_3 * matrix_3_subtract_to (matrix_3 * destination, const matrix_3 * matrix_a, const matrix_3 * matrix_b) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       destination [row] [column] = matrix_a [row] [column] - matrix_b [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_4 * matrix_4_subtract_to (matrix_4 * destination, const matrix_4 * matrix_a, const matrix_4 * matrix_b) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       destination [row] [column] = matrix_a [row] [column] - matrix_b [row] [column];
+               }
+       }
+
+       return (destination);
+}
+
+static matrix_2 * matrix_2_multiply (matrix_2 * result, const matrix_2 * matrix_a, const matrix_2 * matrix_b) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = 0; column < 2; ++column) {
+                       result [row] [column] = 0.0f;
+
+                       for (uint index = 0; index < 2; ++index) {
+                               result [row] [column] += matrix_a [row] [index] * matrix_b [index] [column];
+                       }
+               }
+       }
+
+       return (result);
+}
+
+static matrix_3 * matrix_3_multiply (matrix_3 * result, const matrix_3 * matrix_a, const matrix_3 * matrix_b) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       result [row] [column] = 0.0f;
+
+                       for (uint index = 0; index < 3; ++index) {
+                               result [row] [column] += matrix_a [row] [index] * matrix_b [index] [column];
+                       }
+               }
+       }
+
+       return (result);
+}
+
+static matrix_4 * matrix_4_multiply (matrix_4 * result, const matrix_4 * matrix_a, const matrix_4 * matrix_b) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       result [row] [column] = 0.0f;
+
+                       for (uint index = 0; index < 4; ++index) {
+                               result [row] [column] += matrix_a [row] [index] * matrix_b [index] [column];
+                       }
+               }
+       }
+
+       return (result);
+}
+
+static float matrix_2_trace (const matrix_2 * matrix) {
+       return (matrix [0] [0] + matrix [1] [1]);
+}
+
+static float matrix_3_trace (const matrix_3 * matrix) {
+       return (matrix [0] [0] + matrix [1] [1] + matrix [2] [2]);
+}
+
+static float matrix_4_trace (const matrix_4 * matrix) {
+       return (matrix [0] [0] + matrix [1] [1] + matrix [2] [2] + matrix [3] [3]);
+}
+
+static bool matrix_2_compare (const matrix_2 * matrix_a, const matrix_2 * matrix_b) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = 0; column < 2; ++column) {
+                       if (matrix_a [row] [column] != matrix_b [row] [column]) {
+                               return (false);
+                       }
+               }
+       }
+
+       return (true);
+}
+
+static bool matrix_3_compare (const matrix_3 * matrix_a, const matrix_3 * matrix_b) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       if (matrix_a [row] [column] != matrix_b [row] [column]) {
+                               return (false);
+                       }
+               }
+       }
+
+       return (true);
+}
+
+static bool matrix_4_compare (const matrix_4 * matrix_a, const matrix_4 * matrix_b) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       if (matrix_a [row] [column] != matrix_b [row] [column]) {
+                               return (false);
+                       }
+               }
+       }
+
+       return (true);
+}
+
+static void matrix_2_transpose (matrix_2 * matrix_a, matrix_2 * matrix_b) {
+       for (uint row = 0; row < 2; ++row) {
+               for (uint column = row + 1; column < 2; ++column) {
+                       float temporary = matrix_a [row] [column];
+
+                       matrix_a [row] [column] = matrix_b [column] [row];
+                       matrix_b [column] [row] = temporary;
+               }
+       }
+}
+
+static void matrix_3_transpose (matrix_3 * matrix_a, matrix_3 * matrix_b) {
+       for (uint row = 0; row < 3; ++row) {
+               for (uint column = 0; column < 3; ++column) {
+                       float temporary = matrix_a [row] [column];
+
+                       matrix_a [row] [column] = matrix_b [column] [row];
+                       matrix_b [column] [row] = temporary;
+               }
+       }
+}
+
+static void matrix_4_transpose (matrix_4 * matrix_a, matrix_4 * matrix_b) {
+       for (uint row = 0; row < 4; ++row) {
+               for (uint column = 0; column < 4; ++column) {
+                       float temporary = matrix_a [row] [column];
+
+                       matrix_a [row] [column] = matrix_b [column] [row];
+                       matrix_b [column] [row] = temporary;
+               }
+       }
+}
diff --git a/xcript.h b/xcript.h
new file mode 100755 (executable)
index 0000000..6266e06
--- /dev/null
+++ b/xcript.h
@@ -0,0 +1,383 @@
+///                _       _
+/// __  _____ _ __(_)_ __ | |_
+/// \ \/ / __| '__| | '_ \| __|
+///  >  < (__| |  | | |_) | |_
+/// /_/\_\___|_|  |_| .__/ \__|
+///                 |_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xcript - Whitespace insignificant INI/CFG-like script parser.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+typedef enum {
+       script_unknown, script_comment, script_string,  script_number,  script_marker,  script_header,  script_assign,  script_end,
+       script_from,    script_to,      script_next
+} script_word_type;
+
+typedef struct {
+       char * path;
+       char * source;
+       uint   prefix;
+       uint   length;
+       uint   suffix;
+       uint   offset;
+       uint   line;
+       uint   last_length;
+       char * last_string;
+       bool   force;
+       bool   range;
+} script_structure;
+
+typedef struct {
+       uint     counter;
+       char * * identifier;
+       uint   * index;
+} script_information;
+
+static void script_warning (const script_structure * script, bool condition, const char * message) {
+       if (condition == true) {
+               print ("[/3Warning/-] %s: %i: %s\n", script->path, script->line, message);
+       }
+}
+
+static void script_failure (const script_structure * script, bool condition, const char * message) {
+       if (condition == true) {
+               print ("[/1Failure/-] %s: %i: %s\n", script->path, script->line, message);
+
+               print ("/1%s/-", & script->source [script->offset]);
+
+               exit (log_failure);
+       }
+}
+
+static script_structure * script_open (const char * path) {
+       script_structure * script = allocate (sizeof (* script));
+
+       script->path   = string_duplicate (path);
+       script->source = file_import      (path);
+
+       script->prefix      = 0;
+       script->length      = 0;
+       script->suffix      = 0;
+       script->offset      = 0;
+       script->line        = 1;
+       script->last_length = 0;
+       script->last_string = & script->source [0];
+
+       return (script);
+}
+
+static script_structure * script_close (script_structure * script) {
+       script->path   = deallocate (script->path);
+       script->source = deallocate (script->source);
+
+       return (deallocate (script));
+}
+
+static bool script_compare (const script_structure * script, const char * string) {
+       return (string_compare_limit (string, script->last_string, script->last_length));
+}
+
+static bool script_check (const script_information * information, uint index, const char * identifier) {
+       return (string_compare (identifier, information->identifier [index]));
+}
+
+static char * script_export_string (const script_structure * script) {
+       return (string_duplicate_limit (script->last_string, script->last_length));
+}
+
+static uint script_export_number (const script_structure * script) {
+       return (string_limit_to_number (script->last_string, script->last_length));
+}
+
+static uint script_export_marker (const script_information * information, const script_structure * script) {
+       for (uint counter = 0; counter < information->counter; ++counter) {
+               if (script_compare (script, information->identifier [counter]) == true) {
+                       return (information->index [counter]);
+               }
+       }
+
+       script_failure (script, true, "No such identifier defined so far in any of the headers!");
+
+       return (~ 0u);
+}
+
+static script_word_type script_parser (script_structure * script) {
+       script_word_type word = script_unknown;
+
+       script->prefix = 0;
+       script->length = 0;
+       script->suffix = 0;
+
+       for (; character_is_blank (script->source [script->offset + script->prefix]) == true; ++script->prefix) {
+               if (script->source [script->offset + script->prefix] == '\n') {
+                       ++script->line;
+               }
+       }
+
+       if (script->source [script->offset + script->prefix] == '\0') {
+               word = script_end;
+       } else if (script->source [script->offset + script->prefix] == '(') {
+               script_failure (script, script->range == true, "You are already defining a range, only one pair of () is allowed.");
+               script->range = true;
+               ++script->length;
+               word = script_from;
+       } else if (script->source [script->offset + script->prefix] == ',') {
+               script_failure (script, script->range == false, "You can't use ',' outside of a range.");
+               ++script->length;
+               word = script_next;
+       } else if (script->source [script->offset + script->prefix] == ')') {
+               script_failure (script, script->range == false, "You already defined a range, only one pair of () is allowed.");
+               script->range = false;
+               ++script->length;
+               word = script_to;
+       } else if (script->source [script->offset + script->prefix] == ';') {
+               for (; script->source [script->offset + script->prefix + script->length] != '\n'; ++script->length) {
+                       script_warning (script, script->source [script->offset + script->prefix + script->length] == '\0',
+                                       "Expected at least a trailing new line or some blank character after a comment!");
+               }
+               word = script_comment;
+       } else if (script->source [script->offset + script->prefix] == '#') {
+               for (; script->source [script->offset + script->prefix + script->length] != '\n'; ++script->length) {
+                       script_warning (script, script->source [script->offset + script->prefix + script->length] == '\0',
+                                       "Expected at least a trailing new line or some blank character after a comment!");
+               }
+               word = script_comment;
+       } else if (script->source [script->offset + script->prefix] == '=') {
+               ++script->length;
+               word = script_assign;
+       } else if (script->source [script->offset + script->prefix] == '"') {
+               script_failure (script, script->range == true, "You can't use string inside of a range.");
+               for (script->length = 1; script->source [script->offset + script->prefix + script->length] != '"'; ++script->length) {
+                       script_failure (script, script->source [script->offset + script->prefix + script->length] == '\0',
+                                       "Unterminated string literal, missing '\"' character.");
+               }
+               ++script->prefix;
+               --script->length;
+               ++script->suffix;
+               word = script_string;
+       } else if (script->source [script->offset + script->prefix] == '\'') {
+               script_failure (script, script->range == true, "You can't use string inside of a range.");
+               for (script->length = 1; script->source [script->offset + script->prefix + script->length] != '\''; ++script->length) {
+                       script_failure (script, script->source [script->offset + script->prefix + script->length] == '\0',
+                                       "Unterminated string literal, missing ''' character.");
+               }
+               ++script->prefix;
+               --script->length;
+               ++script->suffix;
+               word = script_string;
+       } else if (script->source [script->offset + script->prefix] == '[') {
+               script_failure (script, script->range == true, "You can't use header inside of a range.");
+               for (; script->source [script->offset + script->prefix + script->length] != ']'; ++script->length) {
+                       script_failure (script, script->source [script->offset + script->prefix + script->length] == '\0',
+                                       "Unterminated header element, missing ']' character.");
+               }
+               ++script->prefix;
+               --script->length;
+               ++script->suffix;
+               word = script_header;
+       } else if (character_is_digit (script->source [script->offset + script->prefix]) == true) {
+               for (; character_is_digit (script->source [script->offset + script->prefix + script->length]) == true; ++script->length) {
+                       script_warning (script, script->source [script->offset + script->prefix + script->length] == '\0',
+                                       "Expected at least a trailing new line or some blank character after a number!");
+               }
+               word = script_number;
+       } else if (character_is_identifier (script->source [script->offset + script->prefix]) == true) {
+               for (; character_is_identifier (script->source [script->offset + script->prefix + script->length]) == true; ++script->length) {
+                       script_warning (script, script->source [script->offset + script->prefix + script->length] == '\0',
+                                       "Expected at least a trailing new line or some blank character after a marker!");
+               }
+               word = script_marker;
+       } else {
+               script_failure (script, true, format ("Illegal character '%c' in script.", script->source [script->offset + script->prefix]));
+       }
+
+       script->last_string = & script->source [script->offset + script->prefix];
+       script->last_length =   script->length;
+
+       script->offset += script->prefix + script->length + script->suffix;
+
+       return (word);
+}
+
+static char * script_expect_header (script_information * information, const script_structure * script, uint index, bool accept) {
+       if (accept == true) {
+               ++information->counter;
+
+               information->identifier = reallocate (information->identifier, information->counter * sizeof (* information->identifier));
+               information->index      = reallocate (information->index,      information->counter * sizeof (* information->index));
+
+               information->identifier [information->counter - 1] = string_duplicate_limit (script->last_string, script->last_length);
+               information->index      [information->counter - 1] = index;
+       }
+
+       return (script_export_string (script));
+}
+
+static char * script_expect_string (script_structure * script) {
+       script_word_type word = script_unknown;
+
+       script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator.");
+       script_failure (script, (word = script_parser (script)) != script_string, "Expected string literal.");
+
+       return (script_export_string (script));
+}
+
+static uint script_expect_number (script_structure * script) {
+       script_word_type word = script_unknown;
+
+       script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator.");
+       script_failure (script, (word = script_parser (script)) != script_number, "Expected number literal.");
+
+       return (script_export_number (script));
+}
+
+static uint script_expect_marker (const script_information * information, script_structure * script) {
+       script_word_type word = script_unknown;
+
+       script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator.");
+       script_failure (script, (word = script_parser (script)) != script_marker, "Expected marker literal.");
+
+       return (script_export_marker (information, script));
+}
+
+static uint script_expect_number_or_marker (const script_information * information, script_structure * script) {
+       script_word_type word = script_unknown;
+
+       script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator.");
+
+       word = script_parser (script);
+
+       if (word == script_number) {
+               return (script_export_number (script));
+       } else if (word == script_marker) {
+               return (script_export_marker (information, script));
+       } else {
+               script_failure (script, true, "Expected number or marker literal.");
+       }
+
+       return (~ 0u);
+}
+
+static uint * script_expect_ordered_array (const script_information * information, script_structure * script, uint * count) {
+       script_word_type word = script_unknown;
+
+       uint   found = 0;
+       uint * array = null;
+
+       script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator.");
+       script_failure (script, (word = script_parser (script)) != script_from,   "Expected '(', begin range operator.");
+
+       for (word = script_parser (script); word != script_to; word = script_parser (script)) {
+               ++found;
+
+               array = reallocate (array, found * sizeof (* array));
+
+               if (word == script_number) {
+                       array [found - 1] = script_export_number (script);
+               } else if (word == script_marker) {
+                       array [found - 1] = script_export_marker (information, script);
+               } else {
+                       script_failure (script, true, "Expected number or marker!");
+               }
+
+               if ((word = script_parser (script)) == script_to) break;
+
+               script_failure (script, word != script_next, "Expected ranged next ','.");
+               script_failure (script, word == script_end,  "Expected ranged to ')'.");
+       }
+
+       (* count) = found;
+
+       return (array);
+}
+
+static uint * script_expect_unordered_array (const script_information * information, script_structure * script, uint count) {
+       script_word_type word = script_unknown;
+
+       uint * array = allocate (count * sizeof (* array));
+
+       script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator.");
+       script_failure (script, (word = script_parser (script)) != script_from,   "Expected '(', begin range operator.");
+
+       for (word = script_parser (script); word != script_to; word = script_parser (script)) {
+               uint index = script_export_marker (information, script);
+
+               script_failure (script, word != script_marker, "Expected ranged marker.");
+
+               script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator.");
+
+               word = script_parser (script);
+
+               if (word == script_number) {
+                       array [index] = script_export_number (script);
+               } else if (word == script_marker) {
+                       array [index] = script_export_marker (information, script);
+               } else {
+                       script_failure (script, true, "Expected number or marker!");
+               }
+
+               if ((word = script_parser (script)) == script_to) break;
+
+               script_failure (script, word != script_next, "Expected ranged next ','.");
+               script_failure (script, word == script_end,  "Expected ranged to ')'.");
+       }
+
+       return (array);
+}
+
+static script_information * script_initialize (const char * general_script_file_path) {
+       script_information * script = allocate (sizeof (* script));
+
+       script_word_type word = script_unknown;
+
+       script_structure * general = script_open (general_script_file_path);
+
+       for (word = script_parser (general); word != script_end; word = script_parser (general)) {
+               if (word == script_header) {
+                       ++script->counter;
+                       script->identifier = reallocate (script->identifier, script->counter * sizeof (* script->identifier));
+                       script->index      = reallocate (script->index,      script->counter * sizeof (* script->index));
+                       script->identifier [script->counter - 1] = string_duplicate_limit (general->last_string, general->last_length);
+                       script->index      [script->counter - 1] = script->counter - 1;
+               } else if ((word == script_end) || (word == script_comment)) {
+                       continue;
+               } else {
+                       script_failure (general, true, "Expected header in general script.");
+               }
+       }
+
+       general = script_close (general);
+
+       return (script);
+}
+
+static script_information * script_deinitialize (script_information * script) {
+       for (uint index = 0; index < script->counter; ++index) {
+               script->identifier [index] = deallocate (script->identifier [index]);
+       }
+
+       script->identifier = deallocate (script->identifier);
+       script->index      = deallocate (script->index);
+
+       return (deallocate (script));
+}
+
+static uint script_indexer (script_information * information, const char * identifier) {
+       for (uint counter = 0; counter < information->counter; ++counter) {
+               if (string_compare (identifier, information->identifier [counter]) == true) {
+                       return (information->index [counter]);
+               }
+       }
+
+       fatal_failure (true, "script_indexer: No such identifier defined so far in any of the headers!");
+
+       return (~ 0u);
+}
diff --git a/xector.h b/xector.h
new file mode 100755 (executable)
index 0000000..22e49b6
--- /dev/null
+++ b/xector.h
@@ -0,0 +1,388 @@
+///                _
+/// __  _____  ___| |_ ___  _ __
+/// \ \/ / _ \/ __| __/ _ \| '__|
+///  >  <  __/ (__| || (_) | |
+/// /_/\_\___|\___|\__\___/|_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xector - Very slow and dumb vector library, mathematical vector, not that C++ cancer by the way...
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+typedef struct {
+       float x, y;
+} vector_2;
+
+typedef struct {
+       float x, y, z;
+} vector_3;
+
+typedef struct {
+       float x, y, z, w;
+} vector_4;
+
+static vector_2 * vector_2_assign (vector_2 * destination, float x, float y) {
+       destination->x = x;
+       destination->y = y;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_assign (vector_3 * destination, float x, float y, float z) {
+       destination->x = x;
+       destination->y = y;
+       destination->z = z;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_assign (vector_4 * destination, float x, float y, float z, float w) {
+       destination->x = x;
+       destination->y = y;
+       destination->z = z;
+       destination->w = w;
+
+       return (destination);
+}
+
+static vector_2 * vector_2_nullify (vector_2 * destination) {
+       destination->x = destination->y = 0.0f;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_nullify (vector_3 * destination) {
+       destination->x = destination->y = destination->z = 0.0f;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_nullify (vector_4 * destination) {
+       destination->x = destination->y = destination->z = destination->w = 0.0f;
+
+       return (destination);
+}
+
+static float vector_2_length (const vector_2 * vector) {
+       const float x = vector->x;
+       const float y = vector->y;
+
+       return (square_root (x * x + y * y));
+}
+
+static float vector_3_length (const vector_3 * vector) {
+       const float x = vector->x;
+       const float y = vector->y;
+       const float z = vector->z;
+
+       return (square_root (x * x + y * y + z * z));
+}
+
+static float vector_4_length (const vector_4 * vector) {
+       const float x = vector->x;
+       const float y = vector->y;
+       const float z = vector->z;
+       const float w = vector->w;
+
+       return (square_root (x * x + y * y + z * z + w * w));
+}
+
+static vector_2 * vector_2_normalize (vector_2 * destination) {
+       const float length = vector_2_length (destination);
+
+       destination->x /= length;
+       destination->y /= length;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_normalize (vector_3 * destination) {
+       const float length = vector_3_length (destination);
+
+       destination->x /= length;
+       destination->y /= length;
+       destination->z /= length;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_normalize (vector_4 * destination) {
+       const float length = vector_4_length (destination);
+
+       destination->x /= length;
+       destination->y /= length;
+       destination->z /= length;
+       destination->w /= length;
+
+       return (destination);
+}
+
+static vector_2 * vector_2_normalize_to (vector_2 * destination, const vector_2 * source) {
+       const float length = vector_2_length (source);
+
+       destination->x = source->x / length;
+       destination->y = source->y / length;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_normalize_to (vector_3 * destination, const vector_3 * source) {
+       const float length = vector_3_length (source);
+
+       destination->x = source->x / length;
+       destination->y = source->y / length;
+       destination->z = source->z / length;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_normalize_to (vector_4 * destination, const vector_4 * source) {
+       const float length = vector_4_length (source);
+
+       destination->x = source->x / length;
+       destination->y = source->y / length;
+       destination->z = source->z / length;
+       destination->w = source->w / length;
+
+       return (destination);
+}
+
+static vector_2 * vector_2_copy (vector_2 * destination, const vector_2 * source) {
+       destination->x = source->x;
+       destination->y = source->y;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_copy (vector_3 * destination, const vector_3 * source) {
+       destination->x = source->x;
+       destination->y = source->y;
+       destination->z = source->z;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_copy (vector_4 * destination, const vector_4 * source) {
+       destination->x = source->x;
+       destination->y = source->y;
+       destination->z = source->z;
+       destination->w = source->w;
+
+       return (destination);
+}
+
+static void vector_2_exchange (vector_2 * vector_a, vector_2 * vector_b) {
+       float_exchange (& vector_a->x, & vector_b->x);
+       float_exchange (& vector_a->y, & vector_b->y);
+}
+
+static void vector_3_exchange (vector_3 * vector_a, vector_3 * vector_b) {
+       float_exchange (& vector_a->x, & vector_b->x);
+       float_exchange (& vector_a->y, & vector_b->y);
+       float_exchange (& vector_a->z, & vector_b->z);
+}
+
+static void vector_4_exchange (vector_4 * vector_a, vector_4 * vector_b) {
+       float_exchange (& vector_a->x, & vector_b->x);
+       float_exchange (& vector_a->y, & vector_b->y);
+       float_exchange (& vector_a->z, & vector_b->z);
+       float_exchange (& vector_a->w, & vector_b->w);
+}
+
+static vector_2 * vector_2_scale (vector_2 * destination, float scale) {
+       destination->x *= scale;
+       destination->y *= scale;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_scale (vector_3 * destination, float scale) {
+       destination->x *= scale;
+       destination->y *= scale;
+       destination->z *= scale;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_scale (vector_4 * destination, float scale) {
+       destination->x *= scale;
+       destination->y *= scale;
+       destination->z *= scale;
+       destination->w *= scale;
+
+       return (destination);
+}
+
+static vector_2 * vector_2_scale_to (vector_2 * destination, const vector_2 * source, float scale) {
+       destination->x = source->x * scale;
+       destination->y = source->y * scale;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_scale_to (vector_3 * destination, const vector_3 * source, float scale) {
+       destination->x = source->x * scale;
+       destination->y = source->y * scale;
+       destination->z = source->z * scale;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_scale_to (vector_4 * destination, const vector_4 * source, float scale) {
+       destination->x = source->x * scale;
+       destination->y = source->y * scale;
+       destination->z = source->z * scale;
+       destination->w = source->w * scale;
+
+       return (destination);
+}
+
+static vector_2 * vector_2_add (vector_2 * destination, const vector_2 * source) {
+       destination->x += source->x;
+       destination->y += source->y;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_add (vector_3 * destination, const vector_3 * source) {
+       destination->x += source->x;
+       destination->y += source->y;
+       destination->z += source->z;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_add (vector_4 * destination, const vector_4 * source) {
+       destination->x += source->x;
+       destination->y += source->y;
+       destination->z += source->z;
+       destination->w += source->w;
+
+       return (destination);
+}
+
+static vector_2 * vector_2_add_to (vector_2 * destination, const vector_2 * vector_a, const vector_2 * vector_b) {
+       destination->x = vector_a->x + vector_b->x;
+       destination->y = vector_a->y + vector_b->y;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_add_to (vector_3 * destination, const vector_3 * vector_a, const vector_3 * vector_b) {
+       destination->x = vector_a->x + vector_b->x;
+       destination->y = vector_a->y + vector_b->y;
+       destination->z = vector_a->z + vector_b->z;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_add_to (vector_4 * destination, const vector_4 * vector_a, const vector_4 * vector_b) {
+       destination->x = vector_a->x + vector_b->x;
+       destination->y = vector_a->y + vector_b->y;
+       destination->z = vector_a->z + vector_b->z;
+       destination->w = vector_a->w + vector_b->w;
+
+       return (destination);
+}
+
+static vector_2 * vector_2_subtract (vector_2 * destination, const vector_2 * source) {
+       destination->x -= source->x;
+       destination->y -= source->y;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_subtract (vector_3 * destination, const vector_3 * source) {
+       destination->x -= source->x;
+       destination->y -= source->y;
+       destination->z -= source->z;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_subtract (vector_4 * destination, const vector_4 * source) {
+       destination->x -= source->x;
+       destination->y -= source->y;
+       destination->z -= source->z;
+       destination->w -= source->w;
+
+       return (destination);
+}
+
+static vector_2 * vector_2_subtract_to (vector_2 * destination, const vector_2 * vector_a, const vector_2 * vector_b) {
+       destination->x = vector_a->x - vector_b->x;
+       destination->y = vector_a->y - vector_b->y;
+
+       return (destination);
+}
+
+static vector_3 * vector_3_subtract_to (vector_3 * destination, const vector_3 * vector_a, const vector_3 * vector_b) {
+       destination->x = vector_a->x - vector_b->x;
+       destination->y = vector_a->y - vector_b->y;
+       destination->z = vector_a->z - vector_b->z;
+
+       return (destination);
+}
+
+static vector_4 * vector_4_subtract_to (vector_4 * destination, const vector_4 * vector_a, const vector_4 * vector_b) {
+       destination->x = vector_a->x - vector_b->x;
+       destination->y = vector_a->y - vector_b->y;
+       destination->z = vector_a->z - vector_b->z;
+       destination->w = vector_a->w - vector_b->w;
+
+       return (destination);
+}
+
+static bool vector_2_compare (const vector_2 * vector_a, const vector_2 * vector_b) {
+       if ((vector_a->x == vector_b->x) && (vector_a->y == vector_b->y)) {
+               return (true);
+       } else {
+               return (false);
+       }
+}
+
+static bool vector_3_compare (const vector_3 * vector_a, const vector_3 * vector_b) {
+       if ((vector_a->x == vector_b->x) && (vector_a->y == vector_b->y) && (vector_a->z == vector_b->z)) {
+               return (true);
+       } else {
+               return (false);
+       }
+}
+
+static bool vector_4_compare (const vector_4 * vector_a, const vector_4 * vector_b) {
+       if ((vector_a->x == vector_b->x) && (vector_a->y == vector_b->y) && (vector_a->z == vector_b->z) && (vector_a->w == vector_b->w)) {
+               return (true);
+       } else {
+               return (false);
+       }
+}
+
+static float vector_2_dot_product (const vector_2 * vector_a, const vector_2 * vector_b) {
+       return (vector_a->x * vector_b->x + vector_a->y * vector_b->y);
+}
+
+static float vector_3_dot_product (const vector_3 * vector_a, const vector_3 * vector_b) {
+       return (vector_a->x * vector_b->x + vector_a->y * vector_b->y + vector_a->z * vector_b->z);
+}
+
+static float vector_4_dot_product (const vector_4 * vector_a, const vector_4 * vector_b) {
+       return (vector_a->x * vector_b->x + vector_a->y * vector_b->y + vector_a->z * vector_b->z + vector_a->w * vector_b->w);
+}
+
+static float vector_2_cross_product (const vector_2 * vector_a, const vector_2 * vector_b) {
+       return (vector_a->x * vector_b->y - vector_a->y * vector_b->x);
+}
+
+static vector_3 * vector_3_cross_product (vector_3 * destination, const vector_3 * source) {
+       destination->x = destination->y * source->z - destination->z * source->y;
+       destination->y = destination->z * source->x - destination->x * source->z;
+       destination->z = destination->x * source->y - destination->y * source->x;
+
+       return (destination);
+}
diff --git a/xhallenge.c b/xhallenge.c
new file mode 100755 (executable)
index 0000000..2e97aa4
--- /dev/null
@@ -0,0 +1,531 @@
+#define use_fatal_failure
+
+#include <xolatile/xtandard.h>
+#include <xolatile/xcript.h>
+#include <xolatile/xerminal.h>
+
+#define challenges_per_day (10)
+#define attribute_minimum  (1)
+#define attribute_maximum  (10)
+
+typedef enum {
+       special_strength,               special_perception,             special_edurance,               special_charisma,
+       special_intelligence,           special_agility,                special_luck,
+       special_count
+} special_enumeration;
+
+typedef struct {
+       uint     count;
+       uint     limit;
+       uint   * completed;
+       uint * * requirement;
+       uint   * type;
+       char * * class;
+       char * * description;
+} challenge_structure;
+
+static const char * special_name [special_count] = {
+       "strength",     "perception",   "edurance",     "charisma",     "intelligence", "agility",      "luck"
+};
+
+static bool challenge_is_repeatable (const challenge_structure * challenges, uint index) {
+       return ((challenges->type [index] == special_strength + 1) ||
+               (challenges->type [index] == special_edurance + 1) ||
+               (challenges->type [index] == special_agility  + 1));
+}
+
+static bool challenge_is_available (const challenge_structure * challenges, uint index) {
+       return ((challenges->completed [index] == 0) || (challenge_is_repeatable (challenges, index) == true));
+}
+
+static bool challenge_is_completable (const uint * special, const challenge_structure * challenges, uint index) {
+       if (challenge_is_available (challenges, index) == false) {
+               return (false);
+       }
+
+       for (uint check = 0; check < special_count; ++check) {
+               if (challenges->requirement [index] [check] > special [check]) {
+                       return (false);
+               }
+       }
+
+       return (true);
+}
+
+static void render_challenge_list (terminal_structure * terminal, const uint * special, const challenge_structure * challenges, uint x, uint y) {
+       uint   count = 0;
+       uint * array = allocate (challenges->count * sizeof (* array));
+
+       for (uint index = 0; index < challenges->count; ++index) {
+               if (challenge_is_completable (special, challenges, index) == true) {
+                       ++count;
+                       array [count - 1] = index;
+               }
+       }
+
+       terminal_render_format (terminal, "Count of unlocked challenges: /2/B%i", x, y + 0, count);
+       terminal_render_format (terminal, "Count of locked challenges:   /1/B%i", x, y + 1, challenges->count - count);
+
+       for (uint index = 0; index < count; ++index) {
+               terminal_render_character (terminal, '[', colour_grey, effect_bold, x, y + index + 2);
+
+               for (uint value = 0; value < special_count; ++value) {
+                       terminal_render_number (terminal, challenges->requirement [array [index]] [value], value + 1, effect_bold, x + 3 * value + 2, y + index + 2);
+               }
+
+               terminal_render_character (terminal, ']', colour_grey, effect_bold, x + special_count * 3 + 1, y + index + 2);
+
+               terminal_render_format (terminal, "/7/B%s/0/B --- /-%s", x + special_count * 3 + 3, y + index + 2,
+                                       challenges->class       [array [index]],
+                                       challenges->description [array [index]]);
+       }
+
+       array = deallocate (array);
+}
+
+static void render_special_attributes (terminal_structure * terminal, const uint * special, uint offset, uint selection) {
+       for (uint index = 0; index < special_count; ++index) {
+               const uint effect = (selection == index) ? effect_bold : effect_normal;
+               const uint length = attribute_maximum + 3;
+
+               char name [32] = "";
+
+               string_copy_limit (name, special_name [index], sizeof (name));
+
+               terminal_render_fill_bar (terminal, special [index], 10, '+', index + 1, effect, 0, index + offset);
+
+               terminal_render_string (terminal, capitalize (name), index + 1, effect, length, index + offset);
+       }
+}
+
+static void prompt_special_attributes (uint * special) {
+       terminal_structure * terminal = terminal_initialize ();
+
+       uint selection = 0;
+       bool show_help = false;
+
+       const char * main_messages [] = {
+               "Press H or Tab to toggle help.",
+               "Press Q or Escape to use default settings.",
+               "Press S or Enter to save changes.",
+               "",
+               "Choose your SPECIAL attributes:"
+       };
+
+       const char * help_messages [] = {
+               "Show help            - H or Tab",
+               "Use default settings - Q or Escape",
+               "Save and quit        - S or Enter",
+               "Move up              - J, Up arrow key or KP8",
+               "Move down            - K, Down arrow key or KP2",
+               "Increase attribute   - P, Right arrow key or KP6",
+               "Decrease attribute   - N, Left arrow key or KP4"
+       };
+
+       for (uint index = 0; index < special_count; ++index) {
+               special [index] = 5;
+       }
+
+       while (terminal->active == true) {
+               terminal_render_background (terminal, ' ', colour_white, effect_normal);
+
+               for (uint index = 0; index < array_length (main_messages); ++index) {
+                       terminal_render_string (terminal, main_messages [index], colour_white, effect_normal, 0, index);
+               }
+
+               render_special_attributes (terminal, special, array_length (main_messages) + 1, selection);
+
+               if (show_help == true) {
+                       for (uint index = 0; index < array_length (help_messages); ++index) {
+                               const uint offset = array_length  (main_messages) + special_count + 2;
+
+                               terminal_render_string (terminal, help_messages [index], colour_white, effect_normal, 0, index + offset);
+                       }
+               }
+
+               terminal_synchronize (terminal);
+
+               if ((terminal->signal [signal_tabulator] == true) || (terminal->signal [signal_h] == true)) {
+                       show_help = ! show_help;
+               } else if ((terminal->signal [signal_escape] == true) || (terminal->signal [signal_q] == true)) {
+                       for (uint index = 0; index < special_count; ++index) {
+                               special [index] = 5;
+                       } break;
+               } else if ((terminal->signal [signal_return] == true) || (terminal->signal [signal_s] == true)) {
+                       break;
+               } else if ((terminal->signal [signal_arrow_up] == true) || (terminal->signal [signal_j] == true)) {
+                       selection = (selection - 1 + special_count) % special_count;
+               } else if ((terminal->signal [signal_arrow_down] == true) || (terminal->signal [signal_k] == true)) {
+                       selection = (selection + 1) % special_count;
+               } else if ((terminal->signal [signal_arrow_left] == true) || (terminal->signal [signal_h] == true)) {
+                       --special [selection];
+                       special [selection] = (special [selection] < 1) ? 1 : special [selection];
+               } else if ((terminal->signal [signal_arrow_right] == true) || (terminal->signal [signal_l] == true)) {
+                       ++special [selection];
+                       special [selection] = (special [selection] > 10) ? 10 : special [selection];
+               }
+       }
+
+       terminal = terminal_deinitialize (terminal);
+}
+
+static void import_user_configuration (uint * special, uint challenge_count, uint * * daily_challenges, bool * * completition) {
+       bool special_defined [special_count] = { false };
+
+       bool daily_challenges_defined = false;
+       bool completition_defined     = false;
+
+       script_information * information = allocate    (sizeof (* information));
+       script_structure   * structure   = script_open (configuration_format ("xhallenge.cfg"));
+
+       for (script_word_type word = script_parser (structure); word != script_end; word = script_parser (structure)) {
+               if (word == script_marker) {
+                       if (script_compare (structure, "challenges") == true) {
+                               uint check = 0;
+                               script_failure (structure, daily_challenges_defined == true, "Challenge array was already defined.");
+                               (* daily_challenges) = script_expect_ordered_array (information, structure, & check);
+                               daily_challenges_defined = true;
+                               script_failure (structure, check != challenges_per_day, "Ordered array 'daily_challenges' is incomplete.");
+                               for (uint index = 0; index < challenges_per_day; ++index) {
+                                       script_failure (structure, (* daily_challenges) [index] >= challenge_count, "Invalid index.");
+                               }
+                       } else if (script_compare (structure, "completition") == true) {
+                               uint check = 0;
+                               script_failure (structure, completition_defined == true, "Completition array was already defined.");
+                               (* completition) = script_expect_ordered_array (information, structure, & check);
+                               completition_defined = true;
+                               script_failure (structure, check != challenges_per_day, "Ordered array 'completition' is incomplete.");
+                       } else for (uint index = 0; index < special_count; ++index) {
+                               if (script_compare (structure, special_name [index]) == true) {
+                                       script_failure (structure, special_defined [index] == true, "Attribute was already defined.");
+                                       special [index] = script_expect_number (structure);
+                                       script_failure (structure, special [index] > attribute_maximum, "Attribute exceeded maximum value.");
+                                       script_failure (structure, special [index] < attribute_minimum, "Attribute exceeded minimum value.");
+                                       special_defined [index] = true;
+                               }
+                       }
+               } else if ((word == script_end) || (word == script_comment)) {
+                       continue;
+               } else {
+                       script_failure (structure, true, "Expected 'marker = number' in configuration script.");
+               }
+       }
+
+       structure   = script_close (structure);
+       information = deallocate   (information);
+}
+
+static void export_user_configuration (const uint * special, const uint * daily_challenges, const bool * completition) {
+       char buffer [4096] = "";
+
+       for (uint index = 0; index < special_count; ++index) {
+               string_concatenate (buffer, format ("%s = %i\n", special_name [index], special [index]));
+       }
+
+       string_concatenate (buffer, "challenges = (");
+       for (uint index = 0; index < challenges_per_day; ++index) {
+               string_concatenate (buffer, number_to_string (daily_challenges [index]));
+
+               if (index < challenges_per_day - 1) {
+                       string_concatenate (buffer, ", ");
+               }
+       }
+       string_concatenate (buffer, ")\n");
+
+       string_concatenate (buffer, "completition = (");
+       for (uint index = 0; index < challenges_per_day; ++index) {
+               string_concatenate (buffer, number_to_string (completition [index]));
+
+               if (index < challenges_per_day - 1) {
+                       string_concatenate (buffer, ", ");
+               }
+       }
+       string_concatenate (buffer, ")\n");
+
+       configuration_export ("xhallenge.cfg", buffer);
+}
+
+static challenge_structure * challenges_initialize (uint limit) {
+       challenge_structure * challenges = allocate (sizeof (* challenges));
+
+       challenges->limit = limit;
+
+       return (challenges);
+}
+
+static challenge_structure * challenges_deinitialize (challenge_structure * challenges) {
+       for (uint index = 0; index < challenges->count; ++index) {
+               challenges->requirement [index] = deallocate (challenges->requirement [index]);
+               challenges->description [index] = deallocate (challenges->description [index]);
+               challenges->class       [index] = deallocate (challenges->class       [index]);
+       }
+
+       challenges->completed   = deallocate (challenges->completed);
+       challenges->requirement = deallocate (challenges->requirement);
+       challenges->type        = deallocate (challenges->type);
+       challenges->class       = deallocate (challenges->class);
+       challenges->description = deallocate (challenges->description);
+
+       return (deallocate (challenges));
+}
+
+static void import_challenges (challenge_structure * challenges) {
+       bool completed_defined   = false;
+       bool requirement_defined = false;
+       bool type_defined        = false;
+       bool class_defined       = false;
+       bool description_defined = false;
+
+       script_information * information = allocate    (sizeof (* information));
+       script_structure   * structure   = script_open (configuration_format ("xhallenge_list.cfg"));
+
+       for (script_word_type word = script_parser (structure); word != script_end; word = script_parser (structure)) {
+               if (word == script_header) {
+                       if (challenges->count > 0) {
+                               script_warning (structure,
+                                               (completed_defined   == false) ||
+                                               (requirement_defined == false) ||
+                                               (type_defined        == false) ||
+                                               (class_defined       == false) ||
+                                               (description_defined == false),
+                                               "Some fields were left uninitialized and default to zero.");
+                       }
+                       ++challenges->count;
+                       challenges->completed   = reallocate (challenges->completed,   challenges->count * sizeof (* challenges->completed));
+                       challenges->requirement = reallocate (challenges->requirement, challenges->count * sizeof (* challenges->requirement));
+                       challenges->type        = reallocate (challenges->type,        challenges->count * sizeof (* challenges->type));
+                       challenges->class       = reallocate (challenges->class,       challenges->count * sizeof (* challenges->class));
+                       challenges->description = reallocate (challenges->description, challenges->count * sizeof (* challenges->description));
+                       completed_defined   = false;
+                       requirement_defined = false;
+                       type_defined        = false;
+                       class_defined       = false;
+                       description_defined = false;
+               } else if (word == script_marker) {
+                       uint current = challenges->count - 1;
+                       if (script_compare (structure, "completed") == true) {
+                               script_failure (structure, completed_defined == true, "Marker 'completed' already defined.");
+                               challenges->completed [current] = script_expect_number (structure);
+                               completed_defined = true;
+                       } else if (script_compare (structure, "requirement") == true) {
+                               uint check = 0;
+                               script_failure (structure, requirement_defined == true, "Marker 'requirement' already defined.");
+                               challenges->requirement [current] = script_expect_ordered_array (information, structure, & check);
+                               requirement_defined = true;
+                               script_failure (structure, check != special_count, "Ordered array doesn't have enough elements.");
+                       } else if (script_compare (structure, "type") == true) {
+                               script_failure (structure, type_defined == true, "Marker 'type' already defined.");
+                               challenges->type [current] = script_expect_number (structure);
+                               type_defined = true;
+                       } else if (script_compare (structure, "class") == true) {
+                               script_failure (structure, class_defined == true, "Marker 'class' already defined.");
+                               challenges->class [current] = script_expect_string (structure);
+                               class_defined = true;
+                       } else if (script_compare (structure, "description") == true) {
+                               script_failure (structure, description_defined == true, "Marker 'description' already defined.");
+                               challenges->description [current] = script_expect_string (structure);
+                               description_defined = true;
+                       } else {
+                               script_failure (structure, true, "Expected name, faction, statistic or ability.");
+                       }
+               } else if ((word == script_end) || (word == script_comment)) {
+                       continue;
+               } else {
+                       script_failure (structure, true, "Expected 'marker = number/string/ordered_array' in configuration script.");
+               }
+       }
+
+       structure   = script_close (structure);
+       information = deallocate   (information);
+}
+
+static void export_challenges (challenge_structure * challenges) {
+       int file = file_open (configuration_format ("xhallenge_list.cfg"), file_flag_edit | file_flag_truncate);
+
+       for (uint index = 0; index < challenges->count; ++index) {
+               file_echo (file, "[] ");
+
+               file_echo (file, format ("completed = %i ", challenges->completed [index]));
+
+               file_echo (file, "requirement = (");
+               for (uint subindex = 0; subindex < special_count; ++subindex) {
+                       file_echo (file, number_to_string (challenges->requirement [index] [subindex]));
+
+                       if (subindex < special_count - 1) {
+                               file_echo (file, ", ");
+                       }
+               }
+               file_echo (file, ") ");
+
+               file_echo (file, format ("type = %i ",             challenges->type        [index]));
+               file_echo (file, format ("class = \"%s\" ",        challenges->class       [index]));
+               file_echo (file, format ("description = \"%s\"\n", challenges->description [index]));
+       }
+
+       file = file_close (file);
+}
+
+static uint generate_challenge (const uint * special, const challenge_structure * challenges) {
+       uint index = urandomize (0, challenges->count - 1);
+       bool valid = false;
+
+       while (valid == false) {
+               valid = true;
+               index = urandomize (0, challenges->count - 1);
+
+               if ((challenges->completed [index] > 0) && (challenges->type [index] != 1) && (challenges->type [index] != 3)) continue;
+
+               for (uint check = 0; check < special_count; ++check) {
+                       if (challenges->requirement [index] [check] > special [check]) {
+                               valid = false;
+                               break;
+                       }
+               }
+       }
+
+       return (index);
+}
+
+static void generate_challenges (const uint * special, const challenge_structure * challenges, uint * * daily_challenges, bool * * completition) {
+       (* daily_challenges) = allocate (challenges_per_day * sizeof (* * daily_challenges));
+       (* completition)     = allocate (challenges_per_day * sizeof (* * completition));
+
+       for (uint index = 0; index < challenges_per_day; ++index) {
+               (* daily_challenges) [index] = generate_challenge (special, challenges);
+       }
+}
+
+static void render_challenges (const uint * special, challenge_structure * challenges, uint * daily_challenges, bool * completition) {
+       terminal_structure * terminal = terminal_initialize ();
+
+       uint selection = 0;
+       bool show_help = false;
+       bool show_list = false;
+
+       const char * main_messages [] = {
+               "Press H or Tab to toggle help.",
+               "Press Q or Escape to quit the program without saving changes.",
+               "Press S or Enter to save changes and quit the program.",
+               "",
+               "Your daily challenges:"
+       };
+
+       const char * help_messages [] = {
+               "Show help          - H or Tab",
+               "Quit               - Q or Escape",
+               "Save and quit      - S or Enter",
+               "Move up            - J, Up arrow key or KP8",
+               "Move down          - K, Down arrow key or KP2",
+               "(Un)Mark challenge - M or Space",
+               "Change challenge   - C or Backspace",
+               "Reset challenges   - R",
+               "List challenges    - L"
+       };
+
+       while (terminal->active == true) {
+               terminal_render_background (terminal, ' ', colour_white, effect_normal);
+
+               for (uint index = 0; index < array_length (main_messages); ++index) {
+                       terminal_render_string (terminal, main_messages [index], colour_white, effect_normal, 0, index);
+               }
+
+               for (uint index = 0; index < challenges_per_day; ++index) {
+                       uint   type        = challenges->type        [daily_challenges [index]];
+                       char * class       = challenges->class       [daily_challenges [index]];
+                       char * description = challenges->description [daily_challenges [index]];
+
+                       const uint effect = (selection == index) ? effect_bold  : effect_normal;
+
+                       const uint offset = array_length (main_messages) + 2;
+
+                       const uint alignment = string_length (class) + 4;
+
+                       terminal_render_toggle (terminal, completition [index], 0, index + offset);
+
+                       terminal_render_string (terminal, class,       type,         effect,      4,             index + offset);
+                       terminal_render_string (terminal, " --- ",     colour_grey,  effect_bold, alignment + 0, index + offset);
+                       terminal_render_string (terminal, description, colour_white, effect,      alignment + 5, index + offset);
+               }
+
+               if (show_list == true) {
+                       render_challenge_list (terminal, special, challenges, 80, 0);
+               }
+
+               if (show_help == true) {
+                       const uint offset = array_length (main_messages) + challenges_per_day + 3;
+
+                       for (uint index = 0; index < array_length (help_messages); ++index) {
+                               terminal_render_string (terminal, help_messages [index], colour_white, effect_normal, 0, index + offset);
+                       }
+
+                       render_special_attributes (terminal, special, offset + array_length (help_messages) + 1, special_count);
+               }
+
+               terminal_synchronize (terminal);
+
+               if ((terminal->signal [signal_tabulator] == true) || (terminal->signal [signal_h] == true)) {
+                       show_help = ! show_help;
+               } else if (/*(terminal->signal [signal_tabulator] == true) || */(terminal->signal [signal_l] == true)) {
+                       show_list = ! show_list;
+               } else if ((terminal->signal [signal_return] == true) || (terminal->signal [signal_s] == true)) {
+                       export_user_configuration (special, daily_challenges, completition);
+                       break;
+               } else if ((terminal->signal [signal_escape] == true) || (terminal->signal [signal_q] == true)) {
+                       break;
+               } else if ((terminal->signal [signal_arrow_up] == true) || (terminal->signal [signal_j] == true)) {
+                       selection = (selection - 1 + challenges_per_day) % challenges_per_day;
+               } else if ((terminal->signal [signal_arrow_down] == true) || (terminal->signal [signal_k] == true)) {
+                       selection = (selection + 1) % challenges_per_day;
+               } else if ((terminal->signal [signal_space] == true) || (terminal->signal [signal_m] == true)) {
+                       completition [selection] = ! completition [selection];
+                       challenges->completed [daily_challenges [selection]] += (completition [selection] == true) ? 1 : -1;
+               } else if ((terminal->signal [signal_backspace] == true) || (terminal->signal [signal_c] == true)) {
+                       daily_challenges [selection] = generate_challenge (special, challenges);
+                       completition     [selection] = false;
+               } else if (/*(terminal->signal [signal_backspace] == true) || */(terminal->signal [signal_r] == true)) {
+                       for (uint index = 0; index < challenges_per_day; ++index) {
+                               daily_challenges [index] = generate_challenge (special, challenges);
+                               completition     [index] = false;
+                       }
+               }
+       }
+
+       terminal = terminal_deinitialize (terminal);
+}
+
+int main (int argc, char * * argv) {
+       uint special [special_count] = { 0 };
+
+       uint * daily_challenges = null;
+       bool * completition     = null;
+
+       challenge_structure * challenges = challenges_initialize (1024);
+
+       randomize_seed_by_time ();
+
+       if (argc == 2) {
+               if (string_compare (argv [1], "-r") == true) {
+                       configuration_remove ("xhallenge.cfg");
+               }
+       }
+
+       import_challenges (challenges);
+
+       if (configuration_exists ("xhallenge.cfg") == true) {
+               import_user_configuration (special, challenges->count, & daily_challenges, & completition);
+       } else {
+               prompt_special_attributes (special);
+               generate_challenges       (special, challenges, & daily_challenges, & completition);
+       }
+
+       render_challenges (special, challenges, daily_challenges, completition);
+
+       export_challenges (challenges);
+
+       challenges = challenges_deinitialize (challenges);
+
+       daily_challenges = deallocate (daily_challenges);
+       completition     = deallocate (completition);
+
+       return (log_success);
+}
diff --git a/xhallenge_list.cfg b/xhallenge_list.cfg
new file mode 100755 (executable)
index 0000000..2ce3364
--- /dev/null
@@ -0,0 +1,433 @@
+[] completed = 0 requirement = (1, 1, 1, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Eshnunna"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Babylon"
+[] completed = 0 requirement = (1, 1, 1, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Shuruppak"
+[] completed = 0 requirement = (1, 1, 1, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Nippur"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Kish"
+[] completed = 0 requirement = (1, 1, 1, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Isin"
+[] completed = 0 requirement = (1, 1, 1, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Umma"
+[] completed = 0 requirement = (1, 1, 2, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Girsu"
+[] completed = 0 requirement = (1, 1, 2, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Lagash"
+[] completed = 0 requirement = (1, 1, 2, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Uruk"
+[] completed = 0 requirement = (1, 1, 2, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Ur"
+[] completed = 0 requirement = (1, 1, 2, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Larsa"
+[] completed = 0 requirement = (1, 1, 2, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Akshak"
+[] completed = 0 requirement = (1, 1, 2, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Akkad"
+[] completed = 0 requirement = (1, 1, 2, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Marda"
+[] completed = 0 requirement = (1, 1, 2, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Adab"
+[] completed = 0 requirement = (1, 1, 3, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Urfa"
+[] completed = 0 requirement = (1, 1, 3, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Carchemish"
+[] completed = 0 requirement = (1, 1, 3, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Hadatu"
+[] completed = 0 requirement = (1, 1, 3, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Nineveh"
+[] completed = 0 requirement = (1, 1, 3, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Nimrud"
+[] completed = 0 requirement = (1, 1, 3, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Assur"
+[] completed = 0 requirement = (1, 1, 3, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Hatra"
+[] completed = 0 requirement = (1, 1, 3, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Mari"
+[] completed = 0 requirement = (1, 1, 3, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Ekallatum"
+[] completed = 0 requirement = (1, 1, 4, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Terqa"
+[] completed = 0 requirement = (1, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Seleucia"
+[] completed = 0 requirement = (1, 1, 4, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Ugarit"
+[] completed = 0 requirement = (1, 1, 4, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Susa"
+[] completed = 0 requirement = (1, 1, 4, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Estakhr"
+[] completed = 0 requirement = (1, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Parsa"
+[] completed = 0 requirement = (1, 1, 4, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Ganzak"
+[] completed = 0 requirement = (1, 1, 4, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Bastam"
+[] completed = 0 requirement = (1, 1, 4, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Pasargad"
+[] completed = 0 requirement = (1, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Neyriz"
+[] completed = 0 requirement = (1, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Gorgan"
+[] completed = 0 requirement = (1, 1, 4, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Ilion"
+[] completed = 0 requirement = (2, 1, 2, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Hattusa"
+[] completed = 0 requirement = (2, 1, 2, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Sardis"
+[] completed = 0 requirement = (2, 1, 2, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Miletus"
+[] completed = 0 requirement = (2, 1, 2, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Nicaea"
+[] completed = 0 requirement = (2, 1, 2, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Sapinuwa"
+[] completed = 0 requirement = (2, 1, 2, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Yazilikaya"
+[] completed = 0 requirement = (2, 1, 2, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Kanesh"
+[] completed = 0 requirement = (2, 1, 2, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Antalia"
+[] completed = 0 requirement = (2, 1, 2, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Mersin"
+[] completed = 0 requirement = (2, 1, 2, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Adana"
+[] completed = 0 requirement = (2, 1, 2, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Melid"
+[] completed = 0 requirement = (2, 1, 3, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Apamea"
+[] completed = 0 requirement = (2, 1, 3, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Jerusalem"
+[] completed = 0 requirement = (2, 1, 3, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Sarepta"
+[] completed = 0 requirement = (2, 1, 3, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Damascus"
+[] completed = 0 requirement = (2, 1, 3, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Adoraim"
+[] completed = 0 requirement = (2, 1, 3, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Tadmor"
+[] completed = 0 requirement = (2, 1, 3, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Ebla"
+[] completed = 0 requirement = (2, 1, 3, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Alalakh"
+[] completed = 0 requirement = (2, 1, 3, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Petra"
+[] completed = 0 requirement = (2, 1, 3, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Bethsaida"
+[] completed = 0 requirement = (2, 1, 3, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Tripoli"
+[] completed = 0 requirement = (2, 1, 4, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Aleppo"
+[] completed = 0 requirement = (2, 1, 4, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Qatna"
+[] completed = 0 requirement = (2, 1, 4, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Bethlehem"
+[] completed = 0 requirement = (2, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Hazor"
+[] completed = 0 requirement = (2, 1, 4, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Ashkelon"
+[] completed = 0 requirement = (2, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Samaria"
+[] completed = 0 requirement = (2, 1, 4, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Byblos"
+[] completed = 0 requirement = (2, 1, 4, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Jawa"
+[] completed = 0 requirement = (2, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Zahiran"
+[] completed = 0 requirement = (2, 1, 4, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Gezer"
+[] completed = 0 requirement = (3, 1, 4, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Jericho"
+[] completed = 0 requirement = (3, 1, 4, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Hama"
+[] completed = 0 requirement = (3, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Nashan"
+[] completed = 0 requirement = (3, 1, 4, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Qatif"
+[] completed = 0 requirement = (3, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Bakkah"
+[] completed = 0 requirement = (3, 1, 4, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Izki"
+[] completed = 0 requirement = (3, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Enkomi"
+[] completed = 0 requirement = (3, 1, 4, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Jebel Barkal"
+[] completed = 0 requirement = (3, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Adulis"
+[] completed = 0 requirement = (3, 1, 4, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Thonis"
+[] completed = 0 requirement = (3, 1, 4, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Idalion"
+[] completed = 0 requirement = (3, 1, 4, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Kerma"
+[] completed = 0 requirement = (3, 1, 5, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Sembel"
+[] completed = 0 requirement = (3, 1, 5, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Abydos"
+[] completed = 0 requirement = (3, 1, 5, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Kition"
+[] completed = 0 requirement = (3, 1, 5, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Meroe"
+[] completed = 0 requirement = (3, 1, 5, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Matara"
+[] completed = 0 requirement = (3, 1, 5, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Taremu"
+[] completed = 0 requirement = (3, 1, 5, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Kourion"
+[] completed = 0 requirement = (3, 1, 5, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Napata"
+[] completed = 0 requirement = (3, 1, 5, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Aksum"
+[] completed = 0 requirement = (3, 1, 5, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Iunu"
+[] completed = 0 requirement = (3, 1, 5, 1, 1, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Memphis"
+[] completed = 0 requirement = (3, 1, 5, 1, 2, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Yamu"
+[] completed = 0 requirement = (3, 1, 5, 1, 3, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Raqote"
+[] completed = 0 requirement = (3, 1, 5, 1, 4, 1, 1) type = 5 class = "Ancient cities" description = "1 page about ancient city of Khito"
+[] completed = 0 requirement = (3, 3, 3, 1, 1, 1, 1) type = 5 class = "Cities" description = "1 page about city of Belgrade"
+[] completed = 0 requirement = (3, 3, 3, 1, 3, 1, 1) type = 5 class = "Cities" description = "1 page about city of Warsaw"
+[] completed = 0 requirement = (3, 3, 3, 1, 2, 1, 1) type = 5 class = "Cities" description = "1 page about city of Ankara"
+[] completed = 0 requirement = (3, 3, 3, 1, 1, 1, 1) type = 5 class = "Cities" description = "1 page about city of Washington"
+[] completed = 0 requirement = (3, 3, 3, 1, 1, 1, 1) type = 5 class = "Cities" description = "1 page about city of London"
+[] completed = 0 requirement = (3, 3, 3, 1, 2, 1, 1) type = 5 class = "Cities" description = "1 page about city of Kiev"
+[] completed = 0 requirement = (3, 3, 3, 1, 2, 1, 1) type = 5 class = "Cities" description = "1 page about city of Cairo"
+[] completed = 0 requirement = (3, 3, 3, 1, 3, 1, 1) type = 5 class = "Cities" description = "1 page about city of Havana"
+[] completed = 0 requirement = (3, 3, 3, 1, 1, 1, 1) type = 5 class = "Cities" description = "1 page about city of Paris"
+[] completed = 0 requirement = (3, 3, 3, 1, 1, 1, 1) type = 5 class = "Cities" description = "1 page about city of Tokyo"
+[] completed = 0 requirement = (3, 3, 3, 1, 3, 1, 1) type = 5 class = "Cities" description = "1 page about city of Nairobi"
+[] completed = 0 requirement = (3, 3, 3, 1, 4, 1, 1) type = 5 class = "Cities" description = "1 page about city of Kingston"
+[] completed = 0 requirement = (3, 3, 3, 1, 1, 1, 1) type = 5 class = "Cities" description = "1 page about city of Berlin"
+[] completed = 0 requirement = (3, 3, 3, 1, 1, 1, 1) type = 5 class = "Cities" description = "1 page about city of Beijing"
+[] completed = 0 requirement = (3, 3, 3, 1, 2, 1, 1) type = 5 class = "Cities" description = "1 page about city of Addis Ababa"
+[] completed = 0 requirement = (3, 3, 3, 1, 2, 1, 1) type = 5 class = "Cities" description = "1 page about city of Brasilia"
+[] completed = 0 requirement = (3, 3, 3, 1, 2, 1, 1) type = 5 class = "Cities" description = "1 page about city of Rome"
+[] completed = 0 requirement = (3, 3, 3, 1, 3, 1, 1) type = 5 class = "Cities" description = "1 page about city of Seoul"
+[] completed = 0 requirement = (3, 3, 3, 1, 3, 1, 1) type = 5 class = "Cities" description = "1 page about city of Rabat"
+[] completed = 0 requirement = (3, 3, 3, 1, 3, 1, 1) type = 5 class = "Cities" description = "1 page about city of Lima"
+[] completed = 0 requirement = (3, 3, 3, 1, 4, 1, 1) type = 5 class = "Cities" description = "1 page about city of Madrid"
+[] completed = 0 requirement = (3, 3, 3, 1, 2, 1, 1) type = 5 class = "Cities" description = "1 page about city of New Delhi"
+[] completed = 0 requirement = (3, 3, 3, 1, 2, 1, 1) type = 5 class = "Cities" description = "1 page about city of Accra"
+[] completed = 0 requirement = (3, 3, 3, 1, 4, 1, 1) type = 5 class = "Cities" description = "1 page about city of Santiago"
+[] completed = 0 requirement = (3, 3, 3, 1, 1, 1, 1) type = 5 class = "Cities" description = "1 page about city of Moscow"
+[] completed = 0 requirement = (3, 3, 3, 1, 4, 1, 1) type = 5 class = "Cities" description = "1 page about city of Bangkok"
+[] completed = 0 requirement = (3, 3, 3, 1, 3, 1, 1) type = 5 class = "Cities" description = "1 page about city of Tunis"
+[] completed = 0 requirement = (3, 3, 3, 1, 3, 1, 1) type = 5 class = "Cities" description = "1 page about city of Bogota"
+[] completed = 0 requirement = (3, 3, 3, 1, 1, 1, 1) type = 5 class = "Cities" description = "1 page about city of Athens"
+[] completed = 0 requirement = (3, 3, 3, 1, 4, 1, 1) type = 5 class = "Cities" description = "1 page about city of Jakarta"
+[] completed = 0 requirement = (3, 3, 3, 1, 4, 1, 1) type = 5 class = "Cities" description = "1 page about city of Dakar"
+[] completed = 0 requirement = (3, 3, 3, 1, 4, 1, 1) type = 5 class = "Cities" description = "1 page about city of Wellington"
+[] completed = 0 requirement = (3, 3, 3, 1, 4, 1, 1) type = 5 class = "Cities" description = "1 page about city of Stockholm"
+[] completed = 0 requirement = (3, 3, 3, 1, 4, 1, 1) type = 5 class = "Cities" description = "1 page about city of Tehran"
+[] completed = 0 requirement = (3, 3, 3, 1, 4, 1, 1) type = 5 class = "Cities" description = "1 page about city of Khartoum"
+[] completed = 0 requirement = (3, 3, 3, 1, 2, 1, 1) type = 5 class = "Cities" description = "1 page about city of Dublin"
+[] completed = 0 requirement = (3, 3, 3, 1, 2, 1, 1) type = 5 class = "Cities" description = "1 page about city of Oslo"
+[] completed = 0 requirement = (3, 3, 3, 1, 3, 1, 1) type = 5 class = "Cities" description = "1 page about city of Hanoi"
+[] completed = 0 requirement = (3, 3, 3, 1, 3, 1, 1) type = 5 class = "Cities" description = "1 page about city of Ottawa"
+[] completed = 0 requirement = (3, 3, 3, 1, 1, 1, 1) type = 5 class = "Cities" description = "1 page about city of Budapest"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Sargon of Akkad (historical figure)"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Hammurabi of Babylon"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Gilgamesh of Uruk"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Naram-Sin of Akkad"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Ashurbanipal of Assur"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Narmer of Egypt"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Khufu of Egypt"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Akhenaten of Egypt"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Agamemnon of Mycenae"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Leonidas I of Sparta"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Pericles of Athens"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Pyrrhus of Epirus"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Cyrus II of Persia"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Darius I of Persia"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Xerxes I of Persia"
+[] completed = 0 requirement = (3, 1, 2, 1, 1, 4, 1) type = 5 class = "People" description = "1 page about Artaxerxes of Persia"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Tang of Shang"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Wu of Zhou"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Duke of Zhou"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Goujian of Yue"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Chandragupta of Maurya"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Ahoka of Maurya"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Hiram I of Tyre"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Ahab of Israel"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Suppiluliuma I of Hattusa"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Muwatalli II of Hattusa"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Hannibal Barca of Carthage"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Numa Pompilus of Rome"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Nebuchadnezzar II of Babylon"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Shalmaneser III of Assur"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Tiglath-Pileser III of Assur"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Psamtik I of Egypt"
+[] completed = 0 requirement = (3, 1, 2, 1, 2, 4, 1) type = 5 class = "People" description = "1 page about Croesus of Lydia"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Esarhaddon of Assur"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Thutmose III of Egypt"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Zimri-Lim of Mari"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Shulgi of Ur"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Eannatum of Lagash"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Piye of Kush"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Bimbisara of Magadha"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Charlemagne of H.R. Empire"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Ivan III of Moscow"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Harsha of India"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Dawit I of Ethiopia"
+[] completed = 0 requirement = (3, 1, 2, 1, 3, 4, 1) type = 5 class = "People" description = "1 page about Alfred of Wessex"
+[] completed = 0 requirement = (3, 1, 2, 1, 4, 4, 1) type = 5 class = "People" description = "1 page about Matilda of Tuscany"
+[] completed = 0 requirement = (3, 1, 2, 1, 4, 4, 1) type = 5 class = "People" description = "1 page about Rajendra I of Chola"
+[] completed = 0 requirement = (3, 1, 2, 1, 4, 4, 1) type = 5 class = "People" description = "1 page about Ibn Battuta of Morocco"
+[] completed = 0 requirement = (3, 1, 2, 1, 4, 4, 1) type = 5 class = "People" description = "1 page about William of Normandy"
+[] completed = 0 requirement = (3, 1, 2, 1, 4, 4, 1) type = 5 class = "People" description = "1 page about Eleanor of Aquitaine"
+[] completed = 0 requirement = (3, 1, 2, 1, 4, 4, 1) type = 5 class = "People" description = "1 page about Suleiman I of Turkey"
+[] completed = 0 requirement = (3, 1, 2, 1, 4, 4, 1) type = 5 class = "People" description = "1 page about Askia of Songhai"
+[] completed = 0 requirement = (3, 1, 2, 1, 5, 4, 1) type = 5 class = "People" description = "1 page about Henry II of England"
+[] completed = 0 requirement = (3, 1, 2, 1, 5, 4, 1) type = 5 class = "People" description = "1 page about Isabella I of Castile"
+[] completed = 0 requirement = (3, 1, 2, 1, 5, 4, 1) type = 5 class = "People" description = "1 page about Hongwu of Ming"
+[] completed = 0 requirement = (3, 1, 2, 1, 5, 4, 1) type = 5 class = "People" description = "1 page about Ibn Khaldun of Tunisia"
+[] completed = 0 requirement = (3, 1, 2, 1, 5, 4, 1) type = 5 class = "People" description = "1 page about Richard of England"
+[] completed = 0 requirement = (3, 1, 2, 1, 5, 4, 1) type = 5 class = "People" description = "1 page about Ferdinand I of Aragon"
+[] completed = 0 requirement = (3, 1, 2, 1, 5, 4, 1) type = 5 class = "People" description = "1 page about Yongle of Ming"
+[] completed = 0 requirement = (3, 1, 2, 1, 5, 4, 1) type = 5 class = "People" description = "1 page about Sigismund of Luxembourg"
+[] completed = 0 requirement = (3, 1, 2, 1, 5, 4, 1) type = 5 class = "People" description = "1 page about Edward I of England"
+[] completed = 0 requirement = (3, 1, 2, 1, 6, 4, 1) type = 5 class = "People" description = "1 page about Justinian I of Byzantine"
+[] completed = 0 requirement = (3, 1, 2, 1, 6, 4, 1) type = 5 class = "People" description = "1 page about Sejong of Korea"
+[] completed = 0 requirement = (3, 1, 2, 1, 6, 4, 1) type = 5 class = "People" description = "1 page about Nzinga A Nkuwu of Kongo"
+[] completed = 0 requirement = (3, 1, 2, 1, 6, 4, 1) type = 5 class = "People" description = "1 page about Philip II of France"
+[] completed = 0 requirement = (3, 1, 2, 1, 6, 4, 1) type = 5 class = "People" description = "1 page about Basil II of Byzantine"
+[] completed = 0 requirement = (3, 1, 2, 1, 6, 4, 1) type = 5 class = "People" description = "1 page about Jayavarman VII of Khmer"
+[] completed = 0 requirement = (3, 1, 2, 1, 6, 4, 1) type = 5 class = "People" description = "1 page about Robert of Scotland"
+[] completed = 0 requirement = (3, 1, 2, 1, 6, 4, 1) type = 5 class = "People" description = "1 page about Louis IX of France"
+[] completed = 0 requirement = (3, 1, 2, 1, 6, 4, 1) type = 5 class = "People" description = "1 page about Kublai Khan of Mongolia"
+[] completed = 0 requirement = (3, 1, 2, 1, 6, 4, 1) type = 5 class = "People" description = "1 page about Alp Arslan of Seljuk"
+[] completed = 0 requirement = (3, 1, 2, 1, 7, 4, 1) type = 5 class = "People" description = "1 page about Theodoric of Ostrogoths"
+[] completed = 0 requirement = (3, 1, 2, 1, 7, 4, 1) type = 5 class = "People" description = "1 page about Frederick I of H.R. Empire"
+[] completed = 0 requirement = (3, 1, 2, 1, 7, 4, 1) type = 5 class = "People" description = "1 page about Genghis Khan of Mongolia"
+[] completed = 0 requirement = (3, 1, 2, 1, 7, 4, 1) type = 5 class = "People" description = "1 page about Mansa Musa of Mali"
+[] completed = 0 requirement = (3, 1, 2, 1, 7, 4, 1) type = 5 class = "People" description = "1 page about Dushan of Serbia"
+[] completed = 0 requirement = (3, 1, 2, 1, 7, 4, 1) type = 5 class = "People" description = "1 page about Otto I of H.R. Empire"
+[] completed = 0 requirement = (3, 1, 2, 1, 7, 4, 1) type = 5 class = "People" description = "1 page about Timur of Timurid"
+[] completed = 0 requirement = (3, 1, 2, 1, 7, 4, 1) type = 5 class = "People" description = "1 page about Ezana of Aksum"
+[] completed = 0 requirement = (3, 1, 2, 1, 7, 4, 1) type = 5 class = "People" description = "1 page about Harald Hardrada of Norway"
+[] completed = 0 requirement = (2, 2, 2, 1, 5, 1, 1) type = 5 class = "Periods" description = "1 page about Hadean eon"
+[] completed = 0 requirement = (2, 2, 2, 1, 5, 1, 1) type = 5 class = "Periods" description = "1 page about Archean eon"
+[] completed = 0 requirement = (2, 2, 2, 1, 5, 1, 1) type = 5 class = "Periods" description = "1 page about Proterozoic eon"
+[] completed = 0 requirement = (2, 2, 2, 1, 5, 1, 1) type = 5 class = "Periods" description = "1 page about Phanerozoic eon"
+[] completed = 0 requirement = (2, 2, 2, 1, 4, 1, 1) type = 5 class = "Periods" description = "1 page about Palaeoproterozoic era"
+[] completed = 0 requirement = (2, 2, 2, 1, 4, 1, 1) type = 5 class = "Periods" description = "1 page about Mesoproterozoic era"
+[] completed = 0 requirement = (2, 2, 2, 1, 4, 1, 1) type = 5 class = "Periods" description = "1 page about Neoproterozoic era"
+[] completed = 0 requirement = (2, 2, 2, 1, 4, 1, 1) type = 5 class = "Periods" description = "1 page about Paleozoic era"
+[] completed = 0 requirement = (2, 2, 2, 1, 4, 1, 1) type = 5 class = "Periods" description = "1 page about Mesozoic era"
+[] completed = 0 requirement = (2, 2, 2, 1, 4, 1, 1) type = 5 class = "Periods" description = "1 page about Cenozoic era"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Cambrian period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Ordovician period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Silurian period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Devonian period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Carboniferous period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Permian period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Triassic period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Jurassic period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Cretaceous period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Paleogene period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Neogene period"
+[] completed = 0 requirement = (2, 2, 2, 1, 3, 1, 1) type = 5 class = "Periods" description = "1 page about Quaternary period"
+[] completed = 0 requirement = (2, 2, 2, 1, 2, 1, 1) type = 5 class = "Periods" description = "1 page about Paleocene epoch"
+[] completed = 0 requirement = (2, 2, 2, 1, 2, 1, 1) type = 5 class = "Periods" description = "1 page about Eocene epoch"
+[] completed = 0 requirement = (2, 2, 2, 1, 2, 1, 1) type = 5 class = "Periods" description = "1 page about Oligocene epoch"
+[] completed = 0 requirement = (2, 2, 2, 1, 2, 1, 1) type = 5 class = "Periods" description = "1 page about Miocene epoch"
+[] completed = 0 requirement = (2, 2, 2, 1, 2, 1, 1) type = 5 class = "Periods" description = "1 page about Mississippian epoch"
+[] completed = 0 requirement = (2, 2, 2, 1, 2, 1, 1) type = 5 class = "Periods" description = "1 page about Pennsylvanian epoch"
+[] completed = 0 requirement = (2, 2, 2, 1, 2, 1, 1) type = 5 class = "Periods" description = "1 page about Pliocene epoch"
+[] completed = 0 requirement = (2, 2, 2, 1, 2, 1, 1) type = 5 class = "Periods" description = "1 page about Pleistocene epoch"
+[] completed = 0 requirement = (2, 2, 2, 1, 2, 1, 1) type = 5 class = "Periods" description = "1 page about Holocene epoch"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 5 class = "Periods" description = "1 page about Stone age"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 5 class = "Periods" description = "1 page about Bronze age"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 5 class = "Periods" description = "1 page about Iron age"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 5 class = "Periods" description = "1 page about Medieval age"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 5 class = "Periods" description = "1 page about Modern age"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 2 class = "Siege weapons" description = "1 page about battering ram"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 2 class = "Siege weapons" description = "1 page about ballista"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 2 class = "Siege weapons" description = "1 page about mangonel"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 2 class = "Siege weapons" description = "1 page about siege tower"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 2 class = "Siege weapons" description = "1 page about siege ladders"
+[] completed = 0 requirement = (1, 2, 1, 1, 2, 1, 1) type = 2 class = "Siege weapons" description = "1 page about onager"
+[] completed = 0 requirement = (1, 2, 1, 1, 2, 1, 1) type = 2 class = "Siege weapons" description = "1 page about trebuchet"
+[] completed = 0 requirement = (1, 2, 1, 1, 2, 1, 1) type = 2 class = "Siege weapons" description = "1 page about springald"
+[] completed = 0 requirement = (1, 2, 1, 1, 2, 1, 1) type = 2 class = "Siege weapons" description = "1 page about siege hook"
+[] completed = 0 requirement = (1, 2, 1, 1, 2, 1, 1) type = 2 class = "Siege weapons" description = "1 page about lithobolos"
+[] completed = 0 requirement = (1, 3, 1, 1, 3, 1, 1) type = 2 class = "Siege weapons" description = "1 page about mantlet"
+[] completed = 0 requirement = (1, 3, 1, 1, 3, 1, 1) type = 2 class = "Siege weapons" description = "1 page about sambuca"
+[] completed = 0 requirement = (1, 3, 1, 1, 3, 1, 1) type = 2 class = "Siege weapons" description = "1 page about harpax"
+[] completed = 0 requirement = (1, 3, 1, 1, 3, 1, 1) type = 2 class = "Siege weapons" description = "1 page about polybolos"
+[] completed = 0 requirement = (1, 3, 1, 1, 3, 1, 1) type = 2 class = "Siege weapons" description = "1 page about oxybeles"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 2 class = "Cold weapons" description = "1 page about arming sword"
+[] completed = 0 requirement = (1, 1, 1, 1, 2, 1, 1) type = 2 class = "Cold weapons" description = "1 page about rapier sword"
+[] completed = 0 requirement = (1, 1, 1, 1, 3, 1, 1) type = 2 class = "Cold weapons" description = "1 page about claymore sword"
+[] completed = 0 requirement = (1, 2, 1, 1, 4, 1, 1) type = 2 class = "Cold weapons" description = "1 page about falchion sword"
+[] completed = 0 requirement = (1, 2, 1, 1, 5, 1, 1) type = 2 class = "Cold weapons" description = "1 page about scimitar sword"
+[] completed = 0 requirement = (1, 2, 1, 1, 6, 1, 1) type = 2 class = "Cold weapons" description = "1 page about sabre sword"
+[] completed = 0 requirement = (1, 3, 1, 1, 7, 1, 1) type = 2 class = "Cold weapons" description = "1 page about khopesh sword"
+[] completed = 0 requirement = (1, 3, 1, 1, 8, 1, 1) type = 2 class = "Cold weapons" description = "1 page about katana sword"
+[] completed = 0 requirement = (1, 3, 1, 1, 9, 1, 1) type = 2 class = "Cold weapons" description = "1 page about jian sword"
+[] completed = 0 requirement = (1, 4, 1, 1, 9, 1, 1) type = 2 class = "Cold weapons" description = "1 page about estoc sword"
+[] completed = 0 requirement = (1, 4, 1, 1, 9, 1, 1) type = 2 class = "Cold weapons" description = "1 page about urumi sword"
+[] completed = 0 requirement = (1, 4, 1, 1, 9, 1, 1) type = 2 class = "Cold weapons" description = "1 page about zweihander sword"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 2 class = "Cold weapons" description = "1 page about Danish axe"
+[] completed = 0 requirement = (1, 1, 1, 1, 2, 1, 1) type = 2 class = "Cold weapons" description = "1 page about bearded axe"
+[] completed = 0 requirement = (1, 1, 1, 1, 3, 1, 1) type = 2 class = "Cold weapons" description = "1 page about franciska axe"
+[] completed = 0 requirement = (1, 2, 1, 1, 4, 1, 1) type = 2 class = "Cold weapons" description = "1 page about labrys axe"
+[] completed = 0 requirement = (1, 2, 1, 1, 5, 1, 1) type = 2 class = "Cold weapons" description = "1 page about sabaris axe"
+[] completed = 0 requirement = (1, 2, 1, 1, 6, 1, 1) type = 2 class = "Cold weapons" description = "1 page about tomahawk axe"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 2 class = "Cold weapons" description = "1 page about halberd"
+[] completed = 0 requirement = (1, 1, 1, 1, 2, 1, 1) type = 2 class = "Cold weapons" description = "1 page about lance"
+[] completed = 0 requirement = (1, 1, 1, 1, 3, 1, 1) type = 2 class = "Cold weapons" description = "1 page about naginata"
+[] completed = 0 requirement = (1, 2, 1, 1, 4, 1, 1) type = 2 class = "Cold weapons" description = "1 page about sarissa"
+[] completed = 0 requirement = (1, 2, 1, 1, 5, 1, 1) type = 2 class = "Cold weapons" description = "1 page about poleaxe"
+[] completed = 0 requirement = (1, 2, 1, 1, 6, 1, 1) type = 2 class = "Cold weapons" description = "1 page about fauchard"
+[] completed = 0 requirement = (1, 3, 1, 1, 7, 1, 1) type = 2 class = "Cold weapons" description = "1 page about glaive"
+[] completed = 0 requirement = (1, 3, 1, 1, 8, 1, 1) type = 2 class = "Cold weapons" description = "1 page about voulge"
+[] completed = 0 requirement = (1, 3, 1, 1, 9, 1, 1) type = 2 class = "Cold weapons" description = "1 page about falx"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 2 class = "Cold weapons" description = "1 page about self bow"
+[] completed = 0 requirement = (1, 2, 1, 1, 2, 1, 1) type = 2 class = "Cold weapons" description = "1 page about composite bow"
+[] completed = 0 requirement = (1, 3, 1, 1, 3, 1, 1) type = 2 class = "Cold weapons" description = "1 page about compound bow"
+[] completed = 0 requirement = (1, 4, 1, 1, 4, 1, 1) type = 2 class = "Cold weapons" description = "1 page about recurve bow"
+[] completed = 0 requirement = (1, 5, 1, 1, 5, 1, 1) type = 2 class = "Cold weapons" description = "1 page about yumi bow"
+[] completed = 0 requirement = (1, 6, 1, 1, 6, 1, 1) type = 2 class = "Cold weapons" description = "1 page about reflex bow"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 3 class = "Plank" description = "10 seconds"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 3 class = "Plank" description = "20 seconds"
+[] completed = 0 requirement = (2, 1, 2, 1, 1, 2, 1) type = 3 class = "Plank" description = "30 seconds"
+[] completed = 0 requirement = (2, 1, 3, 1, 1, 2, 1) type = 3 class = "Plank" description = "40 seconds"
+[] completed = 0 requirement = (3, 1, 4, 1, 1, 3, 1) type = 3 class = "Plank" description = "50 seconds"
+[] completed = 0 requirement = (3, 1, 5, 1, 1, 3, 1) type = 3 class = "Plank" description = "60 seconds"
+[] completed = 0 requirement = (4, 1, 6, 1, 1, 4, 1) type = 3 class = "Plank" description = "70 seconds"
+[] completed = 0 requirement = (4, 1, 7, 1, 1, 4, 1) type = 3 class = "Plank" description = "80 seconds"
+[] completed = 0 requirement = (5, 1, 8, 1, 1, 5, 1) type = 3 class = "Plank" description = "90 seconds"
+[] completed = 0 requirement = (5, 1, 10, 1, 1, 5, 1) type = 3 class = "Plank" description = "100 seconds"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 3 class = "Side plank" description = "10 seconds"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 3 class = "Side plank" description = "20 seconds"
+[] completed = 0 requirement = (2, 1, 2, 1, 1, 2, 1) type = 3 class = "Side plank" description = "30 seconds"
+[] completed = 0 requirement = (2, 1, 3, 1, 1, 2, 1) type = 3 class = "Side plank" description = "40 seconds"
+[] completed = 0 requirement = (3, 1, 4, 1, 1, 3, 1) type = 3 class = "Side plank" description = "50 seconds"
+[] completed = 0 requirement = (3, 1, 5, 1, 1, 3, 1) type = 3 class = "Side plank" description = "60 seconds"
+[] completed = 0 requirement = (4, 1, 6, 1, 1, 4, 1) type = 3 class = "Side plank" description = "70 seconds"
+[] completed = 0 requirement = (4, 1, 7, 1, 1, 4, 1) type = 3 class = "Side plank" description = "80 seconds"
+[] completed = 0 requirement = (5, 1, 8, 1, 1, 5, 1) type = 3 class = "Side plank" description = "90 seconds"
+[] completed = 0 requirement = (5, 1, 10, 1, 1, 5, 1) type = 3 class = "Side plank" description = "100 seconds"
+[] completed = 0 requirement = (3, 1, 5, 1, 1, 1, 1) type = 3 class = "Fist plank" description = "10 seconds"
+[] completed = 0 requirement = (3, 1, 5, 1, 1, 1, 1) type = 3 class = "Fist plank" description = "20 seconds"
+[] completed = 0 requirement = (4, 1, 6, 1, 1, 2, 1) type = 3 class = "Fist plank" description = "30 seconds"
+[] completed = 0 requirement = (4, 1, 6, 1, 1, 2, 1) type = 3 class = "Fist plank" description = "40 seconds"
+[] completed = 0 requirement = (5, 1, 7, 1, 1, 3, 1) type = 3 class = "Fist plank" description = "50 seconds"
+[] completed = 0 requirement = (5, 1, 7, 1, 1, 3, 1) type = 3 class = "Fist plank" description = "60 seconds"
+[] completed = 0 requirement = (6, 1, 8, 1, 1, 4, 1) type = 3 class = "Fist plank" description = "70 seconds"
+[] completed = 0 requirement = (6, 1, 8, 1, 1, 4, 1) type = 3 class = "Fist plank" description = "80 seconds"
+[] completed = 0 requirement = (7, 1, 9, 1, 1, 5, 1) type = 3 class = "Fist plank" description = "90 seconds"
+[] completed = 0 requirement = (7, 1, 10, 1, 1, 5, 1) type = 3 class = "Fist plank" description = "100 seconds"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 1 class = "Push-ups" description = "5 repetitions"
+[] completed = 0 requirement = (2, 1, 1, 1, 1, 1, 1) type = 1 class = "Push-ups" description = "10 repetitions"
+[] completed = 0 requirement = (3, 1, 1, 1, 1, 1, 1) type = 1 class = "Push-ups" description = "15 repetitions"
+[] completed = 0 requirement = (4, 1, 1, 1, 1, 1, 1) type = 1 class = "Push-ups" description = "20 repetitions"
+[] completed = 0 requirement = (5, 1, 1, 1, 1, 1, 1) type = 1 class = "Push-ups" description = "25 repetitions"
+[] completed = 0 requirement = (6, 1, 1, 1, 1, 1, 1) type = 1 class = "Push-ups" description = "30 repetitions"
+[] completed = 0 requirement = (7, 1, 1, 1, 1, 1, 1) type = 1 class = "Push-ups" description = "35 repetitions"
+[] completed = 0 requirement = (8, 1, 1, 1, 1, 1, 1) type = 1 class = "Push-ups" description = "40 repetitions"
+[] completed = 0 requirement = (9, 1, 1, 1, 1, 1, 1) type = 1 class = "Push-ups" description = "45 repetitions"
+[] completed = 0 requirement = (10, 1, 1, 1, 1, 1, 1) type = 1 class = "Push-ups" description = "50 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 1 class = "Fist push-ups" description = "5 repetitions"
+[] completed = 0 requirement = (2, 1, 1, 1, 1, 1, 1) type = 1 class = "Fist push-ups" description = "10 repetitions"
+[] completed = 0 requirement = (3, 2, 1, 1, 1, 1, 1) type = 1 class = "Fist push-ups" description = "15 repetitions"
+[] completed = 0 requirement = (4, 2, 1, 1, 1, 1, 1) type = 1 class = "Fist push-ups" description = "20 repetitions"
+[] completed = 0 requirement = (5, 3, 1, 1, 1, 1, 1) type = 1 class = "Fist push-ups" description = "25 repetitions"
+[] completed = 0 requirement = (6, 3, 1, 1, 1, 1, 1) type = 1 class = "Fist push-ups" description = "30 repetitions"
+[] completed = 0 requirement = (7, 4, 1, 1, 1, 1, 1) type = 1 class = "Fist push-ups" description = "35 repetitions"
+[] completed = 0 requirement = (8, 4, 1, 1, 1, 1, 1) type = 1 class = "Fist push-ups" description = "40 repetitions"
+[] completed = 0 requirement = (9, 5, 1, 1, 1, 1, 1) type = 1 class = "Fist push-ups" description = "45 repetitions"
+[] completed = 0 requirement = (10, 5, 1, 1, 1, 1, 1) type = 1 class = "Fist push-ups" description = "50 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 1 class = "Squats" description = "5 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 2, 1) type = 1 class = "Squats" description = "10 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 3, 1) type = 1 class = "Squats" description = "15 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 4, 1) type = 1 class = "Squats" description = "20 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 5, 1) type = 1 class = "Squats" description = "25 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 6, 1) type = 1 class = "Squats" description = "30 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 7, 1) type = 1 class = "Squats" description = "35 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 8, 1) type = 1 class = "Squats" description = "40 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 9, 1) type = 1 class = "Squats" description = "45 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 10, 1) type = 1 class = "Squats" description = "50 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 1 class = "Crunch" description = "5 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 2, 1) type = 1 class = "Crunch" description = "10 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 3, 1) type = 1 class = "Crunch" description = "15 repetitions"
+[] completed = 0 requirement = (1, 2, 1, 1, 1, 4, 1) type = 1 class = "Crunch" description = "20 repetitions"
+[] completed = 0 requirement = (1, 2, 1, 1, 1, 5, 1) type = 1 class = "Crunch" description = "25 repetitions"
+[] completed = 0 requirement = (1, 2, 1, 1, 1, 6, 1) type = 1 class = "Crunch" description = "30 repetitions"
+[] completed = 0 requirement = (1, 3, 1, 1, 1, 7, 1) type = 1 class = "Crunch" description = "35 repetitions"
+[] completed = 0 requirement = (1, 3, 1, 1, 1, 8, 1) type = 1 class = "Crunch" description = "40 repetitions"
+[] completed = 0 requirement = (1, 3, 1, 1, 1, 9, 1) type = 1 class = "Crunch" description = "45 repetitions"
+[] completed = 0 requirement = (1, 4, 1, 1, 1, 10, 1) type = 1 class = "Crunch" description = "50 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 1 class = "Lunges" description = "5 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 2, 1) type = 1 class = "Lunges" description = "10 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 3, 1) type = 1 class = "Lunges" description = "15 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 4, 1) type = 1 class = "Lunges" description = "20 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 5, 1) type = 1 class = "Lunges" description = "25 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 6, 1) type = 1 class = "Lunges" description = "30 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 7, 1) type = 1 class = "Lunges" description = "35 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 8, 1) type = 1 class = "Lunges" description = "40 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 9, 1) type = 1 class = "Lunges" description = "45 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 10, 1) type = 1 class = "Lunges" description = "50 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 3 class = "Burpees" description = "5 repetitions"
+[] completed = 0 requirement = (2, 1, 2, 1, 1, 2, 1) type = 3 class = "Burpees" description = "10 repetitions"
+[] completed = 0 requirement = (3, 1, 3, 1, 1, 3, 1) type = 3 class = "Burpees" description = "15 repetitions"
+[] completed = 0 requirement = (4, 1, 4, 1, 1, 4, 1) type = 3 class = "Burpees" description = "20 repetitions"
+[] completed = 0 requirement = (5, 1, 5, 1, 1, 5, 1) type = 3 class = "Burpees" description = "25 repetitions"
+[] completed = 0 requirement = (6, 1, 6, 1, 1, 6, 1) type = 3 class = "Burpees" description = "30 repetitions"
+[] completed = 0 requirement = (7, 1, 7, 1, 1, 7, 1) type = 3 class = "Burpees" description = "35 repetitions"
+[] completed = 0 requirement = (8, 1, 8, 1, 1, 8, 1) type = 3 class = "Burpees" description = "40 repetitions"
+[] completed = 0 requirement = (9, 1, 9, 1, 1, 9, 1) type = 3 class = "Burpees" description = "45 repetitions"
+[] completed = 0 requirement = (10, 1, 10, 1, 1, 10, 1) type = 3 class = "Burpees" description = "50 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 1 class = "Sit-ups" description = "5 repetitions"
+[] completed = 0 requirement = (1, 1, 2, 1, 1, 2, 1) type = 1 class = "Sit-ups" description = "10 repetitions"
+[] completed = 0 requirement = (2, 1, 3, 1, 1, 3, 1) type = 1 class = "Sit-ups" description = "15 repetitions"
+[] completed = 0 requirement = (2, 1, 4, 1, 1, 4, 1) type = 1 class = "Sit-ups" description = "20 repetitions"
+[] completed = 0 requirement = (3, 1, 5, 1, 1, 5, 1) type = 1 class = "Sit-ups" description = "25 repetitions"
+[] completed = 0 requirement = (3, 1, 6, 1, 1, 6, 1) type = 1 class = "Sit-ups" description = "30 repetitions"
+[] completed = 0 requirement = (4, 1, 7, 1, 1, 7, 1) type = 1 class = "Sit-ups" description = "35 repetitions"
+[] completed = 0 requirement = (4, 1, 8, 1, 1, 8, 1) type = 1 class = "Sit-ups" description = "40 repetitions"
+[] completed = 0 requirement = (5, 1, 9, 1, 1, 9, 1) type = 1 class = "Sit-ups" description = "45 repetitions"
+[] completed = 0 requirement = (5, 1, 10, 1, 1, 10, 1) type = 1 class = "Sit-ups" description = "50 repetitions"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 7) type = 7 class = "Anti-smoking" description = "smoke less than 20 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 8) type = 7 class = "Anti-smoking" description = "smoke less than 19 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 9) type = 7 class = "Anti-smoking" description = "smoke less than 18 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 1) type = 7 class = "Anti-smoking" description = "smoke less than 17 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 2) type = 7 class = "Anti-smoking" description = "smoke less than 16 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 3) type = 7 class = "Anti-smoking" description = "smoke less than 15 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 4) type = 7 class = "Anti-smoking" description = "smoke less than 14 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 5) type = 7 class = "Anti-smoking" description = "smoke less than 13 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 6) type = 7 class = "Anti-smoking" description = "smoke less than 12 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 1, 1, 1, 7) type = 7 class = "Anti-smoking" description = "smoke less than 11 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 2, 1, 1, 8) type = 7 class = "Anti-smoking" description = "smoke less than 10 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 2, 1, 1, 9) type = 7 class = "Anti-smoking" description = "smoke less than 9 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 2, 1, 1, 1) type = 7 class = "Anti-smoking" description = "smoke less than 8 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 2, 1, 1, 2) type = 7 class = "Anti-smoking" description = "smoke less than 7 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 2, 1, 1, 3) type = 7 class = "Anti-smoking" description = "smoke less than 6 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 2, 1, 1, 4) type = 7 class = "Anti-smoking" description = "smoke less than 5 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 2, 1, 1, 5) type = 7 class = "Anti-smoking" description = "smoke less than 4 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 2, 1, 1, 6) type = 7 class = "Anti-smoking" description = "smoke less than 3 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 2, 1, 1, 7) type = 7 class = "Anti-smoking" description = "smoke less than 2 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 2, 1, 1, 8) type = 7 class = "Anti-smoking" description = "smoke less than 1 cigarettes"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 9) type = 7 class = "Anti-smoking" description = "smoke no cigarettes for entire day"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 1) type = 7 class = "Anti-drinking" description = "drink no alcohol for 1 day"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 2) type = 7 class = "Anti-drinking" description = "drink no alcohol for 2 days"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 3) type = 7 class = "Anti-drinking" description = "drink no alcohol for 3 days"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 4) type = 7 class = "Anti-drinking" description = "drink no alcohol for 4 days"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 5) type = 7 class = "Anti-drinking" description = "drink no alcohol for 5 days"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 6) type = 7 class = "Anti-drinking" description = "drink no alcohol for 6 days"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 7) type = 7 class = "Anti-drinking" description = "drink no alcohol for 7 days"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 8) type = 7 class = "Anti-drinking" description = "drink no alcohol for 8 days"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 9) type = 7 class = "Anti-drinking" description = "drink no alcohol for 9 days"
+[] completed = 0 requirement = (1, 1, 1, 3, 1, 1, 10) type = 7 class = "Anti-drinking" description = "drink no alcohol for 1 week"
+[] completed = 0 requirement = (1, 1, 1, 4, 1, 1, 10) type = 7 class = "Anti-drinking" description = "drink no alcohol for 2 weeks"
+[] completed = 0 requirement = (1, 1, 1, 5, 1, 1, 10) type = 7 class = "Anti-drinking" description = "drink no alcohol for 3 weeks"
+[] completed = 0 requirement = (1, 1, 1, 6, 1, 1, 10) type = 7 class = "Anti-drinking" description = "drink no alcohol for entire month"
diff --git a/xiasma.h b/xiasma.h
new file mode 100755 (executable)
index 0000000..c699e27
--- /dev/null
+++ b/xiasma.h
@@ -0,0 +1,694 @@
+///       _
+/// __  _(_) __ _ ___ _ __ ___   __ _
+/// \ \/ / |/ _` / __| '_ ` _ \ / _` |
+///  >  <| | (_| \__ \ | | | | | (_| |
+/// /_/\_\_|\__,_|___/_| |_| |_|\__,_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xiasma - Less minimalistic statical x86_64, ELF64, GEENOO/Leenoocks bytecode assembler following IA32e.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+#define double_begin   (add)
+#define single_begin   (increment)
+#define static_1_begin (none)
+#define static_2_begin (system_call)
+#define jump_if_begin  (jump_overflow)
+#define move_if_begin  (move_overflow)
+#define set_if_begin   (set_overflow)
+#define float_begin    (float_add)
+#define shift_begin    (rotate_left)
+
+#define jump_not_even          (jump_odd)
+#define jump_not_odd           (jump_even)
+#define jump_not_below         (jump_above_equal)
+#define jump_not_below_equal   (jump_above)
+#define jump_not_above         (jump_below_equal)
+#define jump_not_above_equal   (jump_below)
+#define jump_not_lesser        (jump_greater_equal)
+#define jump_not_lesser_equal  (jump_greater)
+#define jump_not_greater       (jump_lesser_equal)
+#define jump_not_greater_equal (jump_lesser)
+#define move_not_even          (move_odd)
+#define move_not_odd           (move_even)
+#define move_not_below         (move_above_equal)
+#define move_not_below_equal   (move_above)
+#define move_not_above         (move_below_equal)
+#define move_not_above_equal   (move_below)
+#define move_not_lesser        (move_greater_equal)
+#define move_not_lesser_equal  (move_greater)
+#define move_not_greater       (move_lesser_equal)
+#define move_not_greater_equal (move_lesser)
+#define set_not_even           (set_odd)
+#define set_not_odd            (set_even)
+#define set_not_below          (set_above_equal)
+#define set_not_below_equal    (set_above)
+#define set_not_above          (set_below_equal)
+#define set_not_above_equal    (set_below)
+#define set_not_lesser         (set_greater_equal)
+#define set_not_lesser_equal   (set_greater)
+#define set_not_greater        (set_lesser_equal)
+#define set_not_greater_equal  (set_lesser)
+
+#define elf_main_header_size (0x40)
+#define elf_text_sector_size (0x38)
+#define elf_data_sector_size (0x38)
+
+#define elf_header_size (elf_main_header_size + elf_text_sector_size + elf_data_sector_size)
+
+enum {
+       size_8,         size_16,        size_32,        size_64
+};
+
+enum {
+       for_relative,   for_register,   for_memory,     for_immediate
+};
+
+enum {
+       new_memory,                     new_relative,                   new_immediate,
+       add,                            or,                             carry_add,                      carry_subtract,
+       and,                            subtract,                       xor,                            compare,
+       increment,                      decrement,                      not,                            negate,
+       multiply,                       sign_multiply,                  divide,                         sign_divide,
+       float_add,                      float_multiply,                 float_compare,                  float_compare_pop,
+       float_subtract,                 float_unsubtract,               float_divide,                   float_undivide,
+       carry_rotate_left,              carry_rotate_right,             rotate_left,                    rotate_right,
+       shift_left,                     shift_right,                    sign_shift_left,                sign_shift_right,
+       none,                           near_return,                    far_return,                     leave,
+       pop_flags,                      push_flags,
+       system_call,                    cpu_identification,             float_none,                     float_change_sign,
+       float_absolute,                 float_test,                     float_examine,                  float_push_1,
+       float_push_log2_10,             float_push_log2_e,              float_push_pi,                  float_push_log10_2,
+       float_push_ln_2,                float_push_0,                   float_2xm1,                     float_yl2x,
+       float_tangent,                  float_arctangent,               float_extract,                  float_modulus_push_1,
+       float_decrement,                float_increment,                float_modulus,                  float_yl2xp1,
+       float_square_root,              float_sine_cosine,              float_random,                   float_scale,
+       float_sine,                     float_cosine,
+       enter,                          call,                           in,                             out,
+       jump,                           move,                           pop,                            push,
+       jump_overflow,                  jump_not_overflow,              jump_below,                     jump_above_equal,
+       jump_equal,                     jump_not_equal,                 jump_below_equal,               jump_above,
+       jump_sign,                      jump_not_sign,                  jump_even,                      jump_odd,
+       jump_lesser,                    jump_greater_equal,             jump_lesser_equal,              jump_greater,
+       move_overflow,                  move_not_overflow,              move_below,                     move_above_equal,
+       move_equal,                     move_not_equal,                 move_below_equal,               move_above,
+       move_sign,                      move_not_sign,                  move_even,                      move_odd,
+       move_lesser,                    move_greater_equal,             move_lesser_equal,              move_greater,
+       set_overflow,                   set_not_overflow,               set_below,                      set_above_equal,
+       set_equal,                      set_not_equal,                  set_below_equal,                set_above,
+       set_sign,                       set_not_sign,                   set_even,                       set_odd,
+       set_lesser,                     set_greater_equal,              set_lesser_equal,               set_greater,
+       byte_swap,                      test,                           exchange,                       load_address,
+       bit_scan_forward,               bit_scan_reverse,
+       repeat,                         repeat_equal,                   repeat_not_equal,               repeat_zero,
+       repeat_not_zero,                loop,                           loop_equal,                     loop_not_equal
+};
+
+enum {
+       register_0,     register_1,     register_2,     register_3,     register_4,     register_5,     register_6,     register_7,
+       register_8,     register_9,     register_10,    register_11,    register_12,    register_13,    register_14,    register_15
+};
+
+static int   empty_count = 0;
+static int   empty_holes = 1;
+static int * empty_array = null;
+static int * empty_imbue = null;
+static int * empty_store = null;
+
+static int text_sector_size = 0;
+static int data_sector_size = 0;
+
+static unsigned char * text_sector_byte = null;
+static unsigned char * data_sector_byte = null;
+
+static unsigned char elf_main_header_byte [elf_main_header_size] = {
+       0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x03,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
+       0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00,
+       0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char elf_text_sector_byte [elf_text_sector_size] = {
+       0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char elf_data_sector_byte [elf_data_sector_size] = {
+       0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static int front (int data) { return ((data >= register_4) && (data <= register_7));  }
+static int lower (int data) { return ((data >= register_0) && (data <= register_7));  }
+static int upper (int data) { return ((data >= register_8) && (data <= register_15)); }
+
+static int far  (int label) { return (label && 1); }
+static int near (int label) { return (label && 0); }
+
+static void inset (int when, int data) {
+       text_sector_byte [text_sector_size] = (unsigned char) data;
+
+       text_sector_size += (unsigned int) when;
+}
+
+static void inset_immediate (int when, int size, int data) {
+       inset ((when),                              (data >>  0) & 0xff);
+       inset ((when) && (size >= size_16), (data >>  8) & 0xff);
+       inset ((when) && (size >= size_32), (data >> 16) & 0xff);
+       inset ((when) && (size >= size_32), (data >> 24) & 0xff);
+}
+
+static void inset_memory (int when, int size, int data, int base) {
+       empty_array [empty_holes] = text_sector_size;
+       empty_imbue [empty_holes] = data;
+
+       empty_holes += (int) when;
+
+       inset_immediate (when, size, base);
+}
+
+static int store_relative (int * array) {
+       int relative = array [1];
+
+       empty_array [empty_holes] = text_sector_size;
+       empty_imbue [empty_holes] = relative;
+
+       ++empty_holes;
+
+       return (1);
+}
+
+static int store_memory (int * array) {
+       int operation = array [0],
+           memory    = array [1];
+
+       empty_store [memory] = text_sector_size;
+
+       ++empty_count;
+
+       return (1);
+}
+
+static int store_immediate (int * array) {
+       int index     = 0,
+           operation = array [0],
+           size      = array [1],
+           amount    = array [2];
+
+       for (index = 0; index < amount; ++index) {
+               inset_immediate (true, size, array [3 + index]);
+       }
+
+       return (amount + 2);
+}
+
+static void short_prefix (int size) {
+       inset (size == size_16, 0x66);
+}
+
+static void long_prefix (int size, int to, int destination, int from, int source) {
+       int to_upper   = (to   == for_register) && (upper (destination)),
+           from_upper = (from == for_register) && (upper (source)),
+           extension  = (size == size_64);
+
+       inset (extension || to_upper || from_upper, 0x40 + 0x01 * to_upper + 0x04 * from_upper + 0x08 * extension);
+}
+
+static void modify_registers (int to, int destination, int from, int source) {
+       int to_register_from_register = ((to == for_register) && (from == for_register));
+
+       inset (to_register_from_register, 0xc0 + 0x01 * (destination & 0x07) + 0x08 * (source & 0x07));
+}
+
+static void modify_memory (int operation, int to, int from) {
+       int to_register_from_memory  = ((to == for_register) && (from == for_memory)),
+           to_memory_from_register  = ((to == for_memory)   && (from == for_register)),
+           to_memory_from_immediate = ((to == for_memory)   && (from == for_immediate));
+
+       inset (to_register_from_memory || to_memory_from_register, 0x05 + 0x08 * operation * to_memory_from_immediate);
+}
+
+static int build_double (int * array) {
+       int operation   = array [0],
+           size        = array [1],
+           to          = array [2],
+           destination = array [3],
+           from        = array [4],
+           source      = array [5];
+
+       int to_register_from_register  = ((to == for_register) && (from == for_register)),
+           to_register_from_memory    = ((to == for_register) && (from == for_memory)),
+           to_register_from_immediate = ((to == for_register) && (from == for_immediate)),
+           to_register_from_relative  = ((to == for_register) && (from == for_relative)),
+           to_memory_from_register    = ((to == for_memory)   && (from == for_register)),
+           to_memory_from_immediate   = ((to == for_memory)   && (from == for_immediate));
+
+       short_prefix (size);
+
+       long_prefix (size, to, destination, from, source);
+
+       inset (to_register_from_immediate, 0x80 + 0x01 * (size != size_8));
+       inset (to_register_from_immediate, 0xc0 + 0x08 * (operation - double_begin) + 0x01 * (destination & 0x07));
+
+       modify_registers (to, destination, from, source);
+
+       modify_memory (destination, to, from);
+       modify_memory (source,      to, from);
+
+       inset_memory (to_register_from_memory,   size_32, source,      0x1000   - text_sector_size - 4);
+       inset_memory (to_memory_from_register,   size_32, destination, 0x1000   - text_sector_size - 4);
+       inset_memory (to_memory_from_immediate,  size_32, destination, 0x1000   - text_sector_size - 4);
+       inset_memory (to_register_from_relative, size_32, source,      0x4010b0 - text_sector_size - 4);
+
+       inset_immediate (to_register_from_immediate, size, source);
+       inset_immediate (to_memory_from_immediate,   size, source);
+
+       return (5);
+}
+
+static int build_single (int * array) {
+       int operation   = array [0],
+           size        = array [1],
+           to          = array [2],
+           destination = array [3];
+
+       int irregularity = ((operation == increment) || (operation == decrement));
+
+       short_prefix (size);
+
+       long_prefix (size, to, destination, 0, 0);
+
+       inset ((size == size_8) && (to == for_register) && front (destination), 0x40);
+
+       inset (true, 0xf7 + 0x08 * irregularity - 0x01 * (size == size_8));
+
+       inset (to == for_register, 0xc0 + 0x08 * (operation - single_begin) + 0x01 * (destination & 0x07));
+       inset (to == for_memory,   0x05 + 0x08 * (operation - single_begin));
+
+       inset_memory (to == for_memory, size_32, destination, 0x1000 - (text_sector_size + 4));
+
+       return (3);
+}
+
+static int build_static_1 (int * array) {
+       int operation = array [0];
+
+       const unsigned char data  [] = {
+               0x90, 0xc3, 0xcb, 0xc9, 0x9d, 0x9c
+       };
+
+       inset (true, data [operation - static_1_begin]);
+
+       return (0);
+}
+
+static int build_static_2 (int * array) {
+       int operation = array [0];
+
+       const unsigned short data  [] = {
+               0x050f, 0xa20f, 0xd0d9, 0xe0d9, 0xe1d9, 0xe4d9, 0xe5d9, 0xe8d9,
+               0xe9d9, 0xead9, 0xebd9, 0xecd9, 0xedd9, 0xeed9, 0xf0d9, 0xf1d9,
+               0xf2d9, 0xf3d9, 0xf4d9, 0xf5d9, 0xf6d9, 0xf7d9, 0xf8d9, 0xf9d9,
+               0xfad9, 0xfbd9, 0xfcd9, 0xfdd9, 0xfed9, 0xffd9
+       };
+
+       inset_immediate (true, size_16, data [operation - static_2_begin]);
+
+       return (0);
+}
+
+static int build_jump_if (int * array) {
+       int operation = array [0],
+           size      = array [1],
+           location  = array [3];
+
+       inset (far (location) && (size == size_32), 0x0f);
+
+       inset (far  (location), 0x80 + operation - jump_if_begin);
+       inset (near (location), 0x70 + operation - jump_if_begin);
+
+       inset_memory (true, size_32, location, -(text_sector_size + 4));
+
+       return (3);
+}
+
+static int build_move_if (int * array) {
+       int operation   = array [0],
+           size        = array [1],
+           to          = array [2],
+           destination = array [3],
+           from        = array [4],
+           source      = array [5];
+
+       short_prefix (size);
+
+       long_prefix (size, to, destination, from, source);
+
+       inset (true, 0x0f);
+       inset (true, 0x40 + operation - move_if_begin);
+
+       modify_registers (to, destination, from, source);
+
+       modify_memory (destination, to, from);
+
+       return (5);
+}
+
+static int build_set_if (int * array) {
+       int operation   = array [0],
+           to          = array [2],
+           destination = array [3];
+
+       inset ((to == for_register) && (front (destination)), 0x40);
+       inset ((to == for_register) && (upper (destination)), 0x41);
+
+       inset (true, 0x0f);
+       inset (true, 0x90 + operation - set_if_begin);
+
+       inset (to == for_register, 0xc0 + 0x01 * (destination & 0x07));
+       inset (to == for_memory,   0x05);
+
+       inset_memory (to == for_memory, size_32, destination, 0x1000 - (text_sector_size + 4));
+
+       return (3);
+}
+
+static int build_jump (int * array) {
+       int operation   = array [0],
+           size        = array [1],
+           to          = array [2],
+           destination = array [3];
+
+       inset ((to == for_register) && upper (destination), 0X41);
+
+       inset (to == for_relative, 0xe9 + 0x02 * (size == size_8));
+       inset (to == for_register, 0xff);
+       inset (to == for_register, 0xe0 + 0x01 * (destination & 0x07));
+       inset (to == for_memory,   0xff);
+       inset (to == for_memory,   0x25);
+
+       inset_memory (to == for_relative, size_32, destination, -(text_sector_size + 4));
+       inset_memory (to == for_memory,   size_32, destination, 0x4010b0);
+
+       return (3);
+}
+
+static int build_move (int * array) {
+       int operation   = array [0],
+           size        = array [1],
+           to          = array [2],
+           destination = array [3],
+           from        = array [4],
+           source      = array [5],
+           extension   = array [6];
+
+       short_prefix (size);
+
+       long_prefix (size, to, destination, from, source);
+
+       inset ((to == for_register) && (from == for_register), 0x88 + 0x01 * (size != size_8));
+       inset ((to == for_register) && (from == for_memory),   0x8a + 0x01 * (size != size_8));
+       inset ((to == for_memory)   && (from == for_register), 0x88 + 0x01 * (size != size_8));
+
+       modify_memory (destination, to, from);
+       modify_memory (source,      to, from);
+
+       modify_registers (to, destination, from, source);
+
+       inset ((to == for_register) && ((from == for_immediate) || (from == for_relative)), 0xb0 + 0x08 * (size != size_8) + 0x01 * (destination & 0x07));
+
+       inset ((to == for_memory) && (from == for_immediate), 0xc6 + 0x01 * (size != size_8));
+       inset ((to == for_memory) && (from == for_immediate), 0x05);
+
+       inset_memory ((to == for_register) && (from == for_memory),    size_32, source,      0x1000 - text_sector_size - 4);
+       inset_memory ((to == for_memory)   && (from == for_register),  size_32, destination, 0x1000 - text_sector_size - 4);
+       inset_memory ((to == for_memory)   && (from == for_immediate), size_32, destination, 0x1000 - text_sector_size - 4);
+       inset_memory ((to == for_register) && (from == for_relative),  size_32, source,      0x4010b0);
+
+       inset_immediate ((to == for_register) && (from == for_immediate) && (size != size_64), size,            source);
+       inset_immediate ((to == for_memory)   && (from == for_immediate) && (size != size_64), size,            source);
+       inset_immediate ((to == for_register) && (from == for_immediate) && (size == size_64), size_32, source);
+       inset_immediate ((to == for_register) && (from == for_immediate) && (size == size_64), size_32, extension);
+       inset_immediate ((to == for_register) && (from == for_immediate) && (size == size_64), size_32, 0);
+
+       return (5 + (size == size_64));
+}
+
+static int build_call (int * array) {
+       int operation = array [0],
+           from      = array [1],
+           source    = array [2];
+
+       inset ((from == for_register) && (upper (source)), 0x41);
+
+       inset (from == for_relative, 0xe8);
+       inset (from == for_register, 0xff);
+
+       inset_memory (from == for_relative, size_32, source, -(text_sector_size + 4));
+
+       inset (from == for_register, (0xd0 + 0x01 * (source & 0x07)));
+
+       return (2);
+}
+
+static int build_enter (int * array) {
+       int operation       = array [0],
+           dynamic_storage = array [1],
+           nesting_level   = array [2];
+
+       inset (true, 0xc8);
+
+       inset_immediate (true, size_16, dynamic_storage);
+       inset_immediate (true, size_8,  nesting_level & 0x1f);
+
+       return (2);
+}
+
+static int build_float (int * array) {
+       int operation = array [0],
+           size      = array [1],
+           from      = array [2],
+           source    = array [3];
+
+       inset (from == for_memory, 0xd8 + 0x04 * (size == size_64));
+
+       modify_memory (operation, 0, from);
+
+       inset_memory (from == for_memory, size, source, 0);
+
+       return (3);
+}
+
+static int build_shift (int * array) {
+       int operation   = array [0],
+           size        = array [1],
+           to          = array [2],
+           destination = array [3],
+           offset      = array [5];
+
+       short_prefix (size);
+
+       long_prefix (size, to, destination, 0, 0);
+
+       inset (true, 0xc0 + 0x01 * (size != size_8));
+
+       inset (to == for_register, 0x05 + 0x08 * (operation & 7));
+       inset (to == for_memory,   0xc0 + 0x08 * (operation & 7));
+
+       inset_memory    (to == for_memory, size_32, destination, 0x1000 - text_sector_size - 4);
+       inset_immediate (true,                 size_8,  offset);
+
+       return (5);
+}
+
+static int build_in_out (int * array) {
+       int move = array [0],
+           size = array [1],
+           type = array [2],
+           port = array [3];
+
+       short_prefix (size);
+
+       inset (true, 0xe4 + 0x01 * (size != size_8) + 0x02 * (move != out) + 0x08 * (type == for_register));
+
+       inset_immediate (type == for_immediate, size_8, port);
+
+       return (3);
+}
+
+static int build_pop (int * array) {
+       int operation   = array [0],
+           size        = array [1],
+           to          = array [2],
+           destination = array [3];
+
+       short_prefix (size);
+
+       inset ((to == for_register) && (upper (destination)), 0x41);
+
+       inset (to == for_register, 0x58 + 0x01 * (destination & 0x07));
+       inset (to == for_memory,   0x8f);
+       inset (to == for_memory,   0x05);
+
+       inset_memory (to == for_memory, size_32, destination, 0);
+
+       return (3);
+}
+
+static int build_push (int * array) {
+       int operation = array [0],
+           size      = array [1],
+           from      = array [2],
+           source    = array [3];
+
+       short_prefix (size);
+
+       inset ((from == for_register) && (upper (source)), 0x41);
+
+       inset (from == for_register,  0x50 + 0x01 * (source & 0x07));
+       inset (from == for_memory,    0xff);
+       inset (from == for_memory,    0x35);
+       inset (from == for_immediate, 0x68 + 0x02 * (size == size_8));
+
+       inset_memory    (from == for_memory,    size_32, source, 0);
+       inset_immediate (from == for_immediate, size,            source);
+
+       return (3);
+}
+
+static int build_swap (int * array) {
+       int operation   = array [0],
+           size        = array [1],
+           destination = array [3];
+
+       long_prefix (size, for_register, destination, 0, 0);
+
+       inset (true, 0x0f);
+       inset (true, 0xc8 + 0x01 * (destination & 0x07));
+
+       return (3);
+}
+
+static int build_bit_scan (int * array) {
+       int operation   = array [0],
+           size        = array [1],
+           destination = array [3],
+           from        = array [4],
+           source      = array [5];
+
+       short_prefix (size);
+
+       long_prefix (size, for_register, destination, from, source);
+
+       inset_immediate (true, size_16, 0xbc0f);
+
+       modify_registers (for_register, destination, from, source);
+
+       inset (from == for_memory, 0x05 + 0x08 * destination);
+
+       inset_memory (from == for_memory, size_32, source, 0x1000 - (text_sector_size + 4));
+
+       return (5);
+}
+
+static int build_loop (int * array) {
+       int operation = array [0],
+           location  = array [3];
+
+       inset (operation == loop_not_equal, 0xe0);
+       inset (operation == loop_equal,     0xe1);
+       inset (operation == loop,           0xe2);
+
+       inset_memory (1, size_8, location, -(text_sector_size + 1));
+
+       return (3);
+}
+
+static void elf_main_header (void) {
+       int enter = empty_store [0] + 0x4000b0;
+
+       elf_main_header_byte [16] = 0x02;
+       elf_main_header_byte [ 7] = 0x03;
+       elf_main_header_byte [18] = 0x3e;
+
+       memory_copy (& elf_main_header_byte [24], & enter, sizeof (enter));
+}
+
+static void elf_text_sector (unsigned long text_size, unsigned long data_size) {
+       unsigned long text = elf_header_size + text_size - data_size;
+
+       memory_copy (& elf_text_sector_byte [32], & text, (int) sizeof (text));
+       memory_copy (& elf_text_sector_byte [40], & text, (int) sizeof (text));
+}
+
+static void elf_data_sector (unsigned long text_size, unsigned long data_size) {
+       unsigned long data = data_size;
+       unsigned long core = elf_header_size + text_size - data_size;
+       unsigned long move = 0x401000 + core;
+
+       memory_copy (& elf_data_sector_byte [ 8], & core, (int) sizeof (core));
+       memory_copy (& elf_data_sector_byte [16], & move, (int) sizeof (move));
+       memory_copy (& elf_data_sector_byte [24], & move, (int) sizeof (move));
+       memory_copy (& elf_data_sector_byte [32], & data, (int) sizeof (data));
+       memory_copy (& elf_data_sector_byte [40], & data, (int) sizeof (data));
+}
+
+static int (* build_instruction []) (int * array) = {
+       store_memory,   store_relative, store_immediate,
+       build_double,   build_double,   build_double,   build_double,   build_double,   build_double,   build_double,   build_double,
+       build_single,   build_single,   build_single,   build_single,   build_single,   build_single,   build_single,   build_single,
+       build_float,    build_float,    build_float,    build_float,    build_float,    build_float,    build_float,    build_float,
+       build_shift,    build_shift,    build_shift,    build_shift,    build_shift,    build_shift,    build_shift,    build_shift,
+       build_static_1, build_static_1, build_static_1, build_static_1, build_static_1, build_static_1,
+       build_static_2, build_static_2, build_static_2, build_static_2, build_static_2, build_static_2, build_static_2, build_static_2,
+       build_static_2, build_static_2, build_static_2, build_static_2, build_static_2, build_static_2, build_static_2, build_static_2,
+       build_static_2, build_static_2, build_static_2, build_static_2, build_static_2, build_static_2, build_static_2, build_static_2,
+       build_static_2, build_static_2, build_static_2, build_static_2, build_static_2, build_static_2,
+       build_enter,    build_call,     build_in_out,   build_in_out,   build_jump,     build_move,     build_pop,      build_push,
+       build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,
+       build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,  build_jump_if,
+       build_move_if,  build_move_if,  build_move_if,  build_move_if,  build_move_if,  build_move_if,  build_move_if,  build_move_if,
+       build_move_if,  build_move_if,  build_move_if,  build_move_if,  build_move_if,  build_move_if,  build_move_if,  build_move_if,
+       build_set_if,   build_set_if,   build_set_if,   build_set_if,   build_set_if,   build_set_if,   build_set_if,   build_set_if,
+       build_set_if,   build_set_if,   build_set_if,   build_set_if,   build_set_if,   build_set_if,   build_set_if,   build_set_if,
+       build_swap,     build_bit_scan, build_bit_scan, build_loop,     build_loop,     build_loop
+};
+
+static int assemble (int count, int * array) {
+       for (uint index = 0; index < count; ++index) {
+               index += build_instruction [array [index]] (& array [index]);
+       }
+
+       for (uint index = 1; index < empty_holes; ++index) {
+               int set = 0;
+               int get = empty_array [index];
+
+               memory_copy ((char *) & set, (char *) & text_sector_byte [get], (int) sizeof (set));
+
+               set += empty_store [empty_imbue [index]];
+
+               memory_copy ((char *) & text_sector_byte [get], (char *) & set, (int) sizeof (set));
+       }
+
+       return (log_success);
+}
diff --git a/xighlight.c b/xighlight.c
new file mode 100755 (executable)
index 0000000..aa792c6
--- /dev/null
@@ -0,0 +1,127 @@
+///       _       _     _ _       _     _
+/// __  _(_) __ _| |__ | (_) __ _| |__ | |_
+/// \ \/ / |/ _` | '_ \| | |/ _` | '_ \| __|
+///  >  <| | (_| | | | | | | (_| | | | | |_
+/// /_/\_\_|\__, |_| |_|_|_|\__, |_| |_|\__|
+///         |___/           |___/
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xighlight - Generic source code terminal highlighter using VT100 escape sequences, very very slow...
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+#include <xolatile/xtandard.h>
+#include <xolatile/xyntax.h>
+#include <xolatile/xanguage.h>
+
+static void conditionally_exit (language_structure * language, syntax_structure * syntax, bool terminate) {
+       syntax   = syntax_deinitialize   (syntax);
+       language = language_deinitialize (language);
+
+       if (terminate == true) {
+               exit (log_success);
+       }
+}
+
+static void print_common (void) {
+       print ("/B/4xighlight/-: /4Terminal syntax highlighter/-\n\n");
+       print ("\tAuthor:  /4Ognjen 'xolatile' Milan Robovic/-\n");
+       print ("\tLicense: /4GNU//GPLv3/-\n\n");
+}
+
+static void print_help (void) {
+       print_common ();
+
+       print ("Example usage:\n\n");
+       print ("\t/6$ cat file.ext | xighlight [flags]/- /0---/- You need to pass language flag in this case.\n");
+       print ("\t/6$ xighlight [flags] < file.ext/-     /0---/- You need to pass language flag in this case.\n");
+       print ("\t/6$ xighlight file.ext/-               /0---/- Language is automatically detected in this case.\n\n");
+       print ("Supported languages:\n\n");
+
+       for (uint index = 0; index < language_count; ++index) {
+               char align [32] = "";
+
+               print ("\t/B/4%s/- /4%s/- /0---/- %s syntax highlighting\n",
+                      language_short_option (index),
+                      string_align_left (string_copy (align, language_long_option (index)), 9, ' '),
+                      language_identifier (index));
+       }
+}
+
+static void print_version (void) {
+       print_common ();
+
+       print ("\tVersion: /40 (Zero)/-\n");
+}
+
+int main (int argc, char * * argv) {
+       uint   select = language_count;
+       uint   length = 0;
+       char * buffer = null;
+
+       syntax_structure   * syntax   = syntax_initialize   (360);
+       language_structure * language = language_initialize (false);
+
+       for (int argument = 1; argument < argc; ++argument) {
+               if (argument_compare (argv [argument], "-h", "--help") == true) {
+                       print_help         ();
+                       conditionally_exit (language, syntax, true);
+               } else if (argument_compare (argv [argument], "-v", "--version") == true) {
+                       print_version      ();
+                       conditionally_exit (language, syntax, true);
+               }
+
+               for (uint index = 0; index < language_count; ++index) {
+                       if (argument_compare (argv [argument], language_short_option (index), language_long_option (index)) == true) {
+                               (* (language_highlighter (index))) (language, syntax);
+                               select = index;
+                               break;
+                       }
+               }
+
+               if (file_exists (argv [argument]) == true) {
+                       if (select == language_count) {
+                               select = (uint) file_type (argv [argument]);
+                       }
+                       if (buffer == null) {
+                               buffer = file_import (argv [argument]);
+                       }
+               }
+       }
+
+       if (select == language_count) {
+               select = language_common;
+       }
+
+       if (buffer == null) {
+               buffer = record ();
+       }
+
+       language_conditionally_select (language, syntax, select);
+
+       for (uint offset = 0; buffer [offset] != '\0'; offset += length) {
+               select = syntax_select (syntax, & buffer [offset], & length);
+
+               if (select >= syntax->count) {
+                       echo_colour (colour_white, effect_normal);
+               } else {
+                       echo_colour (syntax->colour [select], syntax->effect [select]);
+               }
+
+               output (& buffer [offset], length);
+
+               echo_cancel ();
+       }
+
+       conditionally_exit (language, syntax, false);
+
+       buffer = deallocate (buffer);
+
+       return (log_success);
+}
diff --git a/xogueout b/xogueout
new file mode 100755 (executable)
index 0000000..e19639b
Binary files /dev/null and b/xogueout differ
diff --git a/xogueout.c b/xogueout.c
new file mode 100644 (file)
index 0000000..7011063
--- /dev/null
@@ -0,0 +1,50 @@
+///                                         _
+/// __  _____   __ _ _   _  ___  ___  _   _| |_
+/// \ \/ / _ \ / _` | | | |/ _ \/ _ \| | | | __|
+///  >  < (_) | (_| | |_| |  __/ (_) | |_| | |_
+/// /_/\_\___/ \__, |\__,_|\___|\___/ \__,_|\__|
+///            |___/
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xogueout - Unfun game created for the sole purpose of testing my libraries...
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+#include <xolatile/xtandard.h>
+#include <xolatile/xormat/png.h>
+#include <xolatile/xpengl.h>
+
+int main (void) {
+       opengl_structure * opengl = opengl_initialize (60, 60, false, 1024, 1024);
+
+       int x = 0;
+       int y = 0;
+
+       //~opengl_sprite_import (opengl, "");
+
+       opengl_configure (opengl, 640, 480, "Xogueout");
+
+       while (opengl->active == true) {
+               if (opengl->signal [signal_q] == true) break;
+
+               y = opengl->window_height - 64;
+               x = opengl->cursor_x;
+
+               x = maximum (x, 0);
+               x = minimum (x, opengl->window_width - 96);
+
+               opengl_render_rectangle (opengl, x, y, 96, 32, 0xff7700ff);
+
+               opengl_synchronize (opengl, 0x00000000);
+       }
+
+       opengl = opengl_deinitialize (opengl);
+
+       return (log_success);
+}
diff --git a/xommon.h b/xommon.h
new file mode 100755 (executable)
index 0000000..91ba248
--- /dev/null
+++ b/xommon.h
@@ -0,0 +1,666 @@
+/// __  _____  _ __ ___  _ __ ___   ___  _ __
+/// \ \/ / _ \| '_ ` _ \| '_ ` _ \ / _ \| '_ \
+///  >  < (_) | | | | | | | | | | | (_) | | | |
+/// /_/\_\___/|_| |_| |_|_| |_| |_|\___/|_| |_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xommon - Tiny and elegant XCB wrapper library so I don't have to deal with other people decisions.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+#include <xcb/xcb.h>
+#include <xcb/xcb_atom.h>
+#include <xcb/xcb_image.h>
+//~#include <xcb/composite.h>
+
+#define common_font_width     (8)
+#define common_font_height    (16)
+#define common_font_tabulator (4)
+
+#ifndef common_gameplay_framerate
+#define common_gameplay_framerate (60)
+#endif
+
+#ifndef common_animation_framerate
+#define common_animation_framerate (3)
+#endif
+
+typedef enum {
+       common_window_fullscreen  = 0x1,
+       common_window_transparent = 0x2,
+       common_window_resizable   = 0x4,
+       common_window_decorated   = 0x8
+} common_window_flag;
+
+typedef struct {
+       xcb_connection_t * connection;
+       xcb_screen_t     * screen;
+       xcb_image_t      * image;
+       xcb_window_t       window;
+       xcb_gcontext_t     context;
+       xcb_pixmap_t       pixmap;
+
+       bool signal [signal_count];
+       bool cursor [cursor_count];
+
+       bool      active;
+       uint      window_width;
+       uint      window_height;
+       uint      framerate;
+       ulong     frame_time;
+       ulong     frame_begin;
+       ulong     frame_end;
+       uint    * framebuffer;
+       uint      global_tick;
+       uint      gameplay_tick;
+       uint      animation_tick;
+       int       cursor_x;
+       int       cursor_y;
+       bool      freeze_cursor;
+       bool      freeze_signal;
+       uint      sprite_count;
+       uint      font_count;
+       uint      dummy; /// TODO USE ME PLEASE
+       uint  * * sprite_data;
+       uint    * sprite_width;
+       uint    * sprite_height;
+       uint  * * font_index;
+       uint  * * font_width;
+       uint  * * font_height;
+       char    * font_begin;
+       char    * font_end;
+} common_structure;
+
+static uint common_center_x (const common_structure * common, uint size) {
+       return ((common->window_width - size) / 2);
+}
+
+static uint common_center_y (const common_structure * common, uint size) {
+       return ((common->window_height - size) / 2);
+}
+
+static bool common_cursor_inside (const common_structure * common, int x, int y, uint width, uint height) {
+       return ((common->cursor_x > x)
+            && (common->cursor_y > y)
+            && (common->cursor_x < x + (int) width)
+            && (common->cursor_y < y + (int) height));
+}
+
+static bool common_cursor_left_click (common_structure * common, int x, int y, uint width, uint height) {
+       if (common->cursor [cursor_left] == true) {
+               common->freeze_cursor = true;
+
+               return (common_cursor_inside (common, x, y, width, height) == true);
+       }
+
+       return (false);
+}
+
+static bool common_cursor_right_click (common_structure * common, int x, int y, uint width, uint height) {
+       if (common->cursor [cursor_right]) {
+               common->freeze_cursor = true;
+
+               return (common_cursor_inside (common, x, y, width, height));
+       }
+
+       return (false);
+}
+
+static uint common_sprite_raw_import (common_structure * common, uint * data, uint width, uint height) {
+       ++common->sprite_count;
+
+       common->sprite_data   = reallocate (common->sprite_data,   common->sprite_count * sizeof (* common->sprite_data));
+       common->sprite_width  = reallocate (common->sprite_width,  common->sprite_count * sizeof (* common->sprite_width));
+       common->sprite_height = reallocate (common->sprite_height, common->sprite_count * sizeof (* common->sprite_height));
+
+       common->sprite_data   [common->sprite_count - 1] = data;
+       common->sprite_width  [common->sprite_count - 1] = width;
+       common->sprite_height [common->sprite_count - 1] = height;
+
+       return (common->sprite_count - 1);
+}
+
+static uint common_font_raw_import (common_structure * common, uint * data, uint image_width, char begin, char end, uint empty) {
+       uint   pointer = 0;
+       uint   width   = 0;
+       uint   height  = 0;
+       uint * buffer = null;
+
+       ++common->font_count;
+
+       common->font_index  = reallocate (common->font_index,  common->font_count * sizeof (* common->font_index));
+       common->font_width  = reallocate (common->font_width,  common->font_count * sizeof (* common->font_width));
+       common->font_height = reallocate (common->font_height, common->font_count * sizeof (* common->font_height));
+       common->font_begin  = reallocate (common->font_begin,  common->font_count * sizeof (* common->font_begin));
+       common->font_end    = reallocate (common->font_end,    common->font_count * sizeof (* common->font_end));
+
+       common->font_begin [common->font_count - 1] = begin;
+       common->font_end   [common->font_count - 1] = end;
+
+       common->font_index  [common->font_count - 1] = allocate ((ulong) (end - begin + 1) * sizeof (* * common->font_index));
+       common->font_width  [common->font_count - 1] = allocate ((ulong) (end - begin + 1) * sizeof (* * common->font_width));
+       common->font_height [common->font_count - 1] = allocate ((ulong) (end - begin + 1) * sizeof (* * common->font_height));
+
+       for (char index = begin; index <= end; ++index) {
+               for (          ; data [pointer]                        == empty; ++pointer);
+               for (width  = 0; data [pointer + width]                != empty; ++width);
+               for (height = 0; data [pointer + height * image_width] != empty; ++height);
+
+               buffer = allocate (width * height * sizeof (* buffer));
+
+               for (uint y = 0; y < height; ++y) {
+                       for (uint x = 0; x < width; ++x) {
+                               buffer [y * width + x] = data [pointer + (y * image_width) + x];
+                       }
+               }
+
+               common->font_index  [common->font_count - 1] [index - begin] = common_sprite_raw_import (common, buffer, width, height);
+               common->font_width  [common->font_count - 1] [index - begin] = width;
+               common->font_height [common->font_count - 1] [index - begin] = height;
+
+               pointer += width;
+
+               for (; data [pointer] == empty; ++pointer);
+
+               if (pointer % image_width == 2) {
+                       pointer += height * image_width;
+               }
+       }
+
+       return (common->font_count - 1);
+}
+
+static uint common_sprite_import (common_structure * common, const char * path) {
+       uint   width  = 0;
+       uint   height = 0;
+       uint * data   = null;
+
+       char buffer [256] = "";
+
+#ifdef use_png_library
+       if ((data == null) && (file_exists (string_concatenate (string_copy (buffer, path), ".png")) == true)) {
+               data = png_image_import (buffer, & width, & height);
+       }
+#endif
+
+#ifdef use_jxl_library
+       if ((data == null) && (file_exists (string_concatenate (string_copy (buffer, path), ".jxl")) == true)) {
+               data = jxl_image_import (buffer, & width, & height);
+       }
+#endif
+
+       fatal_failure (data == null, "opengl_sprite_import: Unsupported image format.");
+
+       return (common_sprite_raw_import (common, data, width, height));
+}
+
+static uint common_font_import (common_structure * common, const char * path, char begin, char end, uint colour) {
+       uint   width  = 0;
+       uint   height = 0;
+       uint   result = 0;
+       uint * data   = null;
+
+       char buffer [256] = "";
+
+#ifdef use_png_library
+       if ((data == null) && (file_exists (string_concatenate (string_copy (buffer, path), ".png")) == true)) {
+               data = png_image_import (buffer, & width, & height);
+       }
+#endif
+
+#ifdef use_jxl_library
+       if ((data == null) && (file_exists (string_concatenate (string_copy (buffer, path), ".jxl")) == true)) {
+               data = jxl_image_import (buffer, & width, & height);
+       }
+#endif
+
+       fatal_failure (data == null, "opengl_font_import: Unsupported image format.");
+
+       result = common_font_raw_import (common, data, width, begin, end, colour);
+
+       data = deallocate (data);
+
+       return (result);
+}
+
+static uint common_sprite_width (const common_structure * common, uint sprite) {
+       return (common->sprite_width [sprite]);
+}
+
+static uint common_sprite_height (const common_structure * common, uint sprite) {
+       return (common->sprite_height [sprite]);
+}
+
+static common_structure * common_initialize (void) {
+       common_structure * common = allocate (sizeof (* common));
+
+       return (common);
+}
+
+static common_structure * common_deinitialize (common_structure * common) {
+       for (uint index = 0; index < common->sprite_count; ++index) {
+               common->sprite_data [index] = deallocate (common->sprite_data [index]);
+       }
+
+       for (uint index = 0; index < common->font_count; ++index) {
+               common->font_index  [index] = deallocate (common->font_index  [index]);
+               common->font_width  [index] = deallocate (common->font_width  [index]);
+               common->font_height [index] = deallocate (common->font_height [index]);
+       }
+
+       common->font_index  = deallocate (common->font_index);
+       common->font_width  = deallocate (common->font_width);
+       common->font_height = deallocate (common->font_height);
+       common->font_begin  = deallocate (common->font_begin);
+       common->font_end    = deallocate (common->font_end);
+
+       common->sprite_data   = deallocate (common->sprite_data);
+       common->sprite_width  = deallocate (common->sprite_width);
+       common->sprite_height = deallocate (common->sprite_height);
+
+       common->framebuffer = deallocate (common->framebuffer);
+
+       xcb_free_gc        (common->connection, common->context);
+       xcb_free_pixmap    (common->connection, common->pixmap);
+       xcb_destroy_window (common->connection, common->window);
+
+       xcb_disconnect (common->connection);
+
+       return (deallocate (common));
+}
+
+static void common_configure (common_structure * common, uint width, uint height, const char * title, uint window_flags) {
+       const ulong font_bitmap [190] = {
+               0x0000000000000000, 0x0000000000000000, 0x0000101010101010, 0x1000101000000000, 0x0024242400000000, 0x0000000000000000,
+               0x00002424247e2424, 0x7e24242400000000, 0x0010107c9290907c, 0x1212927c10100000, 0x0000649468081010, 0x202c524c00000000,
+               0x000018242418304a, 0x4444443a00000000, 0x0010101000000000, 0x0000000000000000, 0x0000081020202020, 0x2020100800000000,
+               0x0000201008080808, 0x0808102000000000, 0x000000000024187e, 0x1824000000000000, 0x000000000010107c, 0x1010000000000000,
+               0x0000000000000000, 0x0000101020000000, 0x000000000000007e, 0x0000000000000000, 0x0000000000000000, 0x0000101000000000,
+               0x0000040408081010, 0x2020404000000000, 0x00003c4242464a52, 0x6242423c00000000, 0x0000081828080808, 0x0808083e00000000,
+               0x00003c4242020408, 0x1020407e00000000, 0x00003c4242021c02, 0x0242423c00000000, 0x000002060a122242, 0x7e02020200000000,
+               0x00007e4040407c02, 0x0202423c00000000, 0x00001c2040407c42, 0x4242423c00000000, 0x00007e0202040408, 0x0810101000000000,
+               0x00003c4242423c42, 0x4242423c00000000, 0x00003c424242423e, 0x0202043800000000, 0x0000000000101000, 0x0000101000000000,
+               0x0000000000101000, 0x0000101020000000, 0x0000000408102040, 0x2010080400000000, 0x00000000007e0000, 0x7e00000000000000,
+               0x0000004020100804, 0x0810204000000000, 0x00003c4242420408, 0x0800080800000000, 0x00007c829ea2a2a2, 0xa69a807e00000000,
+               0x00003c424242427e, 0x4242424200000000, 0x00007c4242427c42, 0x4242427c00000000, 0x00003c4242404040, 0x4042423c00000000,
+               0x0000784442424242, 0x4242447800000000, 0x00007e4040407840, 0x4040407e00000000, 0x00007e4040407840, 0x4040404000000000,
+               0x00003c424240404e, 0x4242423c00000000, 0x0000424242427e42, 0x4242424200000000, 0x0000381010101010, 0x1010103800000000,
+               0x00000e0404040404, 0x0444443800000000, 0x0000424448506060, 0x5048444200000000, 0x0000404040404040, 0x4040407e00000000,
+               0x000082c6aa929282, 0x8282828200000000, 0x000042424262524a, 0x4642424200000000, 0x00003c4242424242, 0x4242423c00000000,
+               0x00007c424242427c, 0x4040404000000000, 0x00003c4242424242, 0x42424a3c02000000, 0x00007c424242427c, 0x5048444200000000,
+               0x00003c4240403c02, 0x0242423c00000000, 0x0000fe1010101010, 0x1010101000000000, 0x0000424242424242, 0x4242423c00000000,
+               0x0000424242424224, 0x2424181800000000, 0x0000828282828292, 0x92aac68200000000, 0x0000424224241818, 0x2424424200000000,
+               0x0000828244442810, 0x1010101000000000, 0x00007e0202040810, 0x2040407e00000000, 0x0000382020202020, 0x2020203800000000,
+               0x0000404020201010, 0x0808040400000000, 0x0000380808080808, 0x0808083800000000, 0x0000102844000000, 0x0000000000000000,
+               0x0000000000000000, 0x0000007e00000000, 0x1008000000000000, 0x0000000000000000, 0x00000000003c023e, 0x4242423e00000000,
+               0x00004040407c4242, 0x4242427c00000000, 0x00000000003c4240, 0x4040423c00000000, 0x00000202023e4242, 0x4242423e00000000,
+               0x00000000003c4242, 0x7e40403c00000000, 0x00000e10107c1010, 0x1010101000000000, 0x00000000003e4242, 0x4242423e02023c00,
+               0x00004040407c4242, 0x4242424200000000, 0x0000101000301010, 0x1010103800000000, 0x00000404000c0404, 0x0404040444443800,
+               0x0000404040424448, 0x7048444200000000, 0x0000301010101010, 0x1010103800000000, 0x0000000000fc9292, 0x9292929200000000,
+               0x00000000007c4242, 0x4242424200000000, 0x00000000003c4242, 0x4242423c00000000, 0x00000000007c4242, 0x4242427c40404000,
+               0x00000000003e4242, 0x4242423e02020200, 0x00000000005e6040, 0x4040404000000000, 0x00000000003e4040, 0x3c02027c00000000,
+               0x00001010107c1010, 0x1010100e00000000, 0x0000000000424242, 0x4242423e00000000, 0x0000000000424242, 0x2424181800000000,
+               0x0000000000828292, 0x9292927c00000000, 0x0000000000424224, 0x1824424200000000, 0x0000000000424242, 0x4242423e02023c00,
+               0x00000000007e0408, 0x1020407e00000000, 0x00000c1010102010, 0x1010100c00000000, 0x0000101010101010, 0x1010101000000000,
+               0x0000300808080408, 0x0808083000000000, 0x000000000062928c, 0x0000000000000000
+       };
+
+       const uint event_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
+
+       uint mask_window_flags [2] = { 0 };
+
+       (void) window_flags;
+
+       uint * dumb_buffer = allocate (256 * sizeof (* dumb_buffer));
+
+       for (uint index = 0; index < 256; ++index) {
+               dumb_buffer [index] = 0xffffffff;
+       }
+
+       ++common->font_count;
+
+       common->font_index  = reallocate (common->font_index,  common->font_count * sizeof (* common->font_index));
+       common->font_width  = reallocate (common->font_width,  common->font_count * sizeof (* common->font_width));
+       common->font_height = reallocate (common->font_height, common->font_count * sizeof (* common->font_height));
+       common->font_begin  = reallocate (common->font_begin,  common->font_count * sizeof (* common->font_begin));
+       common->font_end    = reallocate (common->font_end,    common->font_count * sizeof (* common->font_end));
+
+       common->font_begin [common->font_count - 1] = ' ';
+       common->font_end   [common->font_count - 1] = '~';
+
+       common->font_index  [common->font_count - 1] = allocate (95 * sizeof (* * common->font_index));
+       common->font_width  [common->font_count - 1] = allocate (95 * sizeof (* * common->font_width));
+       common->font_height [common->font_count - 1] = allocate (95 * sizeof (* * common->font_height));
+
+       for (uint index = 0; index < 95; ++index) {
+               uint * buffer = allocate (common_font_width * common_font_height * sizeof (* buffer));
+
+               for (uint value = 0; value < 2; ++value) {
+                       for (uint bit = 64; bit > 0; --bit) {
+                               uint destination = ((value << 3) - ((bit - 1) >> 3) + 7) * common_font_width - ((bit - 1) & 7) + 7;
+                               uint source      = (font_bitmap [2 * index + value] >> (bit - 1)) & 1;
+
+                               buffer [destination] = (source) ? 0xffffffff : 0x00000000;
+                       }
+               }
+
+               common->font_index  [common->font_count - 1] [index] = common_sprite_raw_import (common, buffer, common_font_width, common_font_height);
+               common->font_width  [common->font_count - 1] [index] = common_font_width;
+               common->font_height [common->font_count - 1] [index] = common_font_height;
+       }
+
+       common_sprite_raw_import (common, dumb_buffer, 16, 16);
+
+       common->window_width  = width;
+       common->window_height = height;
+
+       //~if (window_flags == ~ 0u) {
+               //~flags = common_window_decorated | common_window_resizable;
+       //~} else {
+               //~flags = window_flags;
+       //~}
+
+       common->connection = xcb_connect (null, null);
+
+       common->screen = xcb_setup_roots_iterator (xcb_get_setup (common->connection)).data;
+
+       common->window  = xcb_generate_id (common->connection);
+       common->context = xcb_generate_id (common->connection);
+       common->pixmap  = xcb_generate_id (common->connection);
+
+       mask_window_flags [0] = common->screen->black_pixel;
+       mask_window_flags [1] = XCB_EVENT_MASK_NO_EVENT        |
+                               XCB_EVENT_MASK_EXPOSURE        |
+                               XCB_EVENT_MASK_RESIZE_REDIRECT |
+                               XCB_EVENT_MASK_KEY_RELEASE     |
+                               XCB_EVENT_MASK_KEY_PRESS       |
+                               XCB_EVENT_MASK_BUTTON_RELEASE  |
+                               XCB_EVENT_MASK_BUTTON_PRESS;
+
+       xcb_create_window (common->connection, common->screen->root_depth, common->window, common->screen->root, 0, 0, (ushort) width,
+                          (ushort) height, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, common->screen->root_visual, event_mask, mask_window_flags);
+
+       xcb_map_window (common->connection, common->window);
+
+       //~xcb_composite_redirect_window (common->connection, common->window, XCB_COMPOSITE_REDIRECT_MANUAL);
+
+       xcb_change_property (common->connection, XCB_PROP_MODE_REPLACE, common->window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8,
+                            (uint) string_length (title), title);
+
+       xcb_create_pixmap (common->connection, common->screen->root_depth, common->pixmap, common->window, (ushort) width, (ushort ) height);
+
+       xcb_create_gc (common->connection, common->context, common->pixmap, 0, null);
+
+       xcb_flush (common->connection);
+
+       common->framebuffer = allocate (width * height * sizeof (* common->framebuffer));
+
+       common->active = true;
+
+       common->frame_begin = nano_time ();
+}
+
+static void common_synchronize (common_structure * common, uint colour) {
+       const uint signal_code [signal_count] = {
+               0,
+               38,     56,     54,     40,     26,     41,     42,     43,     31,     44,     45,     46,     58,     57,     32,     33,
+               24,     27,     39,     28,     30,     55,     25,     53,     29,     52,     19,     10,     11,     12,     13,     14,
+               15,     16,     17,     18,     9,      23,     36,     36,     61,     51,     47,     49,     65,     22,     60,     59,
+               48,     66,     20,     21,     34,     35,     37,     105,    50,     62,     64,     108,    67,     68,     69,     70,
+               71,     72,     73,     74,     75,     76,     95,     96,     111,    116,    113,    114,    77,     127,    118,    110,
+               112,    119,    115,    117,    86,     82,     63,     106,    104,    91,     90,     87,     88,     89,     83,     84,
+               85,     79,     80,     81
+       };
+
+       xcb_generic_event_t * generic_event = xcb_wait_for_event (common->connection);
+       //~xcb_generic_event_t * generic_event = null;
+
+       (void) colour;
+
+       //~for (; ; ) {
+               //~generic_event = xcb_poll_for_event (common->connection);
+
+               //~if (generic_event != null) {
+                       //~if ((generic_event->response_type & 127) != 14) break;
+               //~}
+       //~}
+
+       xcb_flush (common->connection);
+
+       print ("%i\n", generic_event->response_type & 127);
+//~XCB_NO_EXPOSURE = 14
+       //~if (generic_event != null) {
+       switch (generic_event->response_type & 127) {
+               //~case XCB_EXPOSE: {
+                       //~xcb_flush (common->connection);
+               //~} break;
+               //~case XCB_MOTION_NOTIFY: {
+                       //~;
+               //~} break;
+               case (XCB_BUTTON_PRESS): {
+                       xcb_button_press_event_t * button_press = (xcb_button_press_event_t *) generic_event;
+                       if (button_press->detail == 1) common->cursor [cursor_left]   = true;
+                       if (button_press->detail == 2) common->cursor [cursor_middle] = true;
+                       if (button_press->detail == 3) common->cursor [cursor_right]  = true;
+                       common->cursor_x = button_press->event_x;
+                       common->cursor_y = button_press->event_y;
+               } break;
+               case (XCB_BUTTON_RELEASE): {
+                       xcb_button_release_event_t * button_release = (xcb_button_release_event_t *) generic_event;
+                       if (button_release->detail == 1) common->cursor [cursor_left]   = false;
+                       if (button_release->detail == 2) common->cursor [cursor_middle] = false;
+                       if (button_release->detail == 3) common->cursor [cursor_right]  = false;
+                       common->cursor_x = button_release->event_x;
+                       common->cursor_y = button_release->event_y;
+               } break;
+               case (XCB_KEY_PRESS): {
+                       xcb_key_press_event_t * key_press = (xcb_key_press_event_t *) generic_event;
+                       for (uint index = 0; index < signal_count; ++index) {
+                               if (key_press->detail == signal_code [index]) {
+                                       common->signal [index] = true;
+                               }
+                       }
+               } break;
+               case (XCB_KEY_RELEASE): {
+                       xcb_key_release_event_t * key_release = (xcb_key_release_event_t *) generic_event;
+                       for (uint index = 0; index < signal_count; ++index) {
+                               if (key_release->detail == signal_code [index]) {
+                                       common->signal [index] = false;
+                               }
+                       }
+               } break;
+               default: {
+               } break;
+       }
+
+       generic_event = deallocate (generic_event);
+       //~}
+
+       for (uint pixel = 0; pixel < common->window_width * common->window_height; ++pixel) {
+               uint r = (common->framebuffer [pixel] & 0x00ff0000) >> 16;
+               uint b = (common->framebuffer [pixel] & 0x000000ff) << 16;
+
+               common->framebuffer [pixel] = (common->framebuffer [pixel] & 0xff00ff00) | b | r;
+       }
+
+       common->image = xcb_image_create_native (common->connection, (ushort) common->window_width, (ushort) common->window_height,
+                                               XCB_IMAGE_FORMAT_Z_PIXMAP, common->screen->root_depth, common->framebuffer,
+                                               (uint) (common->window_width * common->window_height * sizeof (* common->framebuffer)),
+                                               (uchar *) common->framebuffer);
+
+       xcb_image_put (common->connection, common->pixmap, common->context, common->image, 0, 0, 0);
+
+       xcb_image_destroy (common->image);
+
+       xcb_copy_area (common->connection, common->pixmap, common->window, common->context, 0, 0, 0, 0, (ushort) common->window_width,
+                      (ushort) common->window_height);
+
+       common->framebuffer = allocate (common->window_width * common->window_height * sizeof (* common->framebuffer));
+
+       common->frame_end = nano_time ();
+
+       common->frame_time = common->frame_end - common->frame_begin;
+
+       if (common->frame_time < 1000000000ul / common_gameplay_framerate) {
+               nano_wait (1000000000ul / common_gameplay_framerate - common->frame_time);
+       }
+
+       if (common->global_tick % common_gameplay_framerate == 0) {
+               common->framerate = (uint) (1000000000ul / common->frame_time);
+       }
+
+       ++common->global_tick;
+
+       common->global_tick    = common->global_tick % (common_gameplay_framerate * common_animation_framerate);
+       common->gameplay_tick  = common->global_tick % (common_gameplay_framerate);
+       common->animation_tick = common->global_tick / (common_gameplay_framerate / common_animation_framerate);
+
+       common->frame_begin = nano_time ();
+}
+
+static void common_render_base (common_structure * common, uint sprite, int x, int y, uint u, uint v, uint width, uint height, float scale_x, float scale_y, int flip_x,
+                                int flip_y, uint upper_left, uint upper_right, uint lower_left, uint lower_right) {
+       (void) scale_x;
+       (void) scale_y;
+       (void) flip_x;
+       (void) flip_y;
+       /// FIX TO INTERPOLATE ALL 4 COLOURS
+       //~(void) upper_left;
+       (void) upper_right;
+       (void) lower_left;
+       (void) lower_right;
+
+       /// COLOUR INTERPOLATION WITH RBGA-ABGR CONVERSION
+       uint interpolate_pixels (uint pixel, uint modifier) {
+               const uint r = (((pixel & 0xff000000) >> 24) * ((modifier & 0x000000ff) >>  0)) / 0xff;
+               const uint g = (((pixel & 0x00ff0000) >> 16) * ((modifier & 0x0000ff00) >>  8)) / 0xff;
+               const uint b = (((pixel & 0x0000ff00) >>  8) * ((modifier & 0x00ff0000) >> 16)) / 0xff;
+               const uint a = (((pixel & 0x000000ff) >>  0) * ((modifier & 0xff000000) >> 24)) / 0xff;
+
+               return ((r << 24) | (g << 16) | (b << 8) | a);
+       }
+
+       if ((x + (int) width < 0) || (y + (int) height < 0) || (x > (int) common->window_width) || (y > (int) common->window_height)) return;
+
+       for (uint vertical = 0; vertical < height; ++vertical) {
+               if (vertical + y >= common->window_height) break;
+               if (vertical + v >= common->sprite_height [sprite]) break;
+
+               for (uint horizontal = 0; horizontal < width; ++horizontal) {
+                       if (horizontal + x >= common->window_width) break;
+                       if (horizontal + u >= common->sprite_width [sprite]) break;
+
+                       const uint pixel = common->sprite_data [sprite] [(vertical + v) * common->sprite_width [sprite] + horizontal + u];
+                       const uint at = (y + vertical) * common->window_width + (x + horizontal);
+
+                       common->framebuffer [at] = (((pixel & 0xff000000) >> 24) > 0x77) ? interpolate_pixels (pixel, upper_left) : common->framebuffer [at];
+               }
+       }
+}
+
+static void common_render_rectangle (common_structure * common, int x, int y, uint width, uint height, uint colour) {
+       common_render_base (common, common->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16, (float) height / 16, 0, 0, colour, colour,
+                           colour, colour);
+}
+
+static void common_render_rectangle_gradient_v (common_structure * common, int x, int y, uint width, uint height, uint colour_up, uint colour_down) {
+       common_render_base (common, common->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16, (float) height / 16, 0, 0, colour_up, colour_up,
+                           colour_down, colour_down);
+}
+
+static void common_render_rectangle_gradient_h (common_structure * common, int x, int y, uint width, uint height, uint colour_left, uint colour_right) {
+       common_render_base (common, common->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16, (float) height / 16, 0, 0, colour_left,
+                           colour_right, colour_left, colour_right);
+}
+
+static void common_render_sprite (common_structure * common, uint sprite, int x, int y) {
+       common_render_base (common, sprite, x, y, 0, 0, common->sprite_width [sprite], common->sprite_height [sprite], 1, 1, 0, 0, 0xffffffffu, 0xffffffffu, 0xffffffffu,
+                           0xffffffffu);
+}
+
+static void common_render_sprite_crop (common_structure * common, uint sprite, int x, int y, uint u, uint v, uint width, uint height) {
+       common_render_base (common, sprite, x, y, u, v, width, height, 1, 1, 0, 0, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+}
+
+static void common_render_sprite_colour (common_structure * common, uint sprite, uint colour, int x, int y) {
+       common_render_base (common, sprite, x, y, 0, 0, common->sprite_width [sprite], common->sprite_height [sprite], 1, 1, 0, 0, colour, colour, colour, colour);
+}
+
+static void common_render_sprite_crop_colour (common_structure * common, uint sprite, uint colour, int x, int y, uint u, uint v, uint width, uint height) {
+       common_render_base (common, sprite, x, y, u, v, width, height, 1, 1, 0, 0, colour, colour, colour, colour);
+}
+
+static void common_render_sprite_flip (common_structure * common, uint sprite, int x, int y, int flip_x, int flip_y) {
+       common_render_base (common, sprite, x, y, 0, 0, common->sprite_width [sprite], common->sprite_height [sprite], 1, 1, flip_x, flip_y, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+}
+
+static void common_render_sprite_animate (common_structure * common, uint sprite, int x, int y, uint frames, uint state, uint states) {
+       uint width  = common->sprite_width  [sprite] / states;
+       uint height = common->sprite_height [sprite] / frames;
+       uint u      = width  * (state                 % states);
+       uint v      = height * (common->animation_tick % frames);
+
+       common_render_sprite_crop (common, sprite, x, y, u, v, width, height);
+}
+
+static void common_render_sprite_preview (common_structure * common, uint sprite, int x, int y, uint u, uint v, uint width, uint height, float zoom) {
+       common_render_base (common, sprite, x, y, u, v, width, height, zoom, zoom, false, false, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+}
+
+static void common_render_sprite_control (common_structure * common, uint sprite, int x, int y, uint u, uint v, uint width, uint height, int flip_x, int flip_y) {
+       common_render_base (common, sprite, x, y, u, v, width, height, 1, 1, flip_x, flip_y, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+}
+
+static uint common_render_string_width (common_structure * common, const char * string, uint font, float scale) {
+       uint length = 0;
+
+       if (string == null) {
+               return (0);
+       }
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               uint character = common->font_index [font] [string [index] - common->font_begin [font]];
+
+               length += (uint) ((float) common->sprite_width [character] * scale);
+       }
+
+       return (length);
+}
+
+static void common_render_string (common_structure * common, const char * string, uint font, int x, int y, float scale, uint colour) {
+       int offset = x;
+
+       if (string == null) return;
+
+       if (font == 0xffffffffu) {
+               font = common->font_count - 1;
+       }
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               uint character = 0;
+
+               if (string [index] == '\t') {
+                       x += (int) (scale * (float) common_font_tabulator * (float) common->sprite_width [common->font_index [font] [' ' - common->font_begin [font]]]);
+                       continue;
+               } else if (string [index] == '\n') {
+                       x  = offset;
+                       y += (int) (scale * (float) common->sprite_height [common->font_index [font] [' ' - common->font_begin [font]]]);
+                       continue;
+               } else if ((string [index] >= common->font_begin [font]) && (string [index] <= common->font_end [font])) {
+                       character = common->font_index [font] [string [index] - common->font_begin [font]];
+               } else {
+                       continue;
+               }
+
+               common_render_base (common, character, x, y, 0, 0, common->sprite_width [character], common->sprite_height [character],
+                                    scale, scale, 0, 0, colour, colour, colour, colour);
+
+               x += (int) (scale * (float) common->sprite_width [character]);
+       }
+}
diff --git a/xop.c b/xop.c
new file mode 100755 (executable)
index 0000000..dc6aeeb
--- /dev/null
+++ b/xop.c
@@ -0,0 +1,43 @@
+#include <xolatile/xtandard.h>
+
+static void echo_byte (uchar byte) {
+       output ("0123456789ABCDEF" + byte / 16, 1);
+       output ("0123456789ABCDEF" + byte % 16, 1);
+
+       output (" ", 1);
+}
+
+int main (int argc, char * * argv) {
+       int     file   = 0;
+       ulong   size   = 0;
+       uchar * buffer = null;
+
+       if (argc != 2) {
+               print ("> xop input_file\n");
+
+               return (log_failure);
+       }
+
+       file = file_open (argv [1], file_flag_read);
+       size = file_size (argv [1]);
+
+       buffer = allocate (size * sizeof (* buffer));
+
+       file_read (file, buffer, size);
+
+       file = file_close (file);
+
+       for (ulong offset = 0; offset < size; ++offset) {
+               if (buffer [offset] == 0x90) {
+                       echo ("\n");
+               }
+
+               echo_byte (buffer [offset]);
+       }
+
+       echo ("\n");
+
+       buffer = deallocate (buffer);
+
+       return (log_success);
+}
diff --git a/xormat.h b/xormat.h
new file mode 100644 (file)
index 0000000..992d710
--- /dev/null
+++ b/xormat.h
@@ -0,0 +1,122 @@
+///                                 _
+/// __  _____  _ __ _ __ ___   __ _| |_
+/// \ \/ / _ \| '__| '_ ` _ \ / _` | __|
+///  >  < (_) | |  | | | | | | (_| | |_
+/// /_/\_\___/|_|  |_| |_| |_|\__,_|\__|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xormat - Very simple file format wrapper for things I hate but have to use anyway...
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+#ifdef use_png_library
+#include <xolatile/xormat/png.h>
+#endif
+
+#ifdef use_jxl_library
+#include <xolatile/xormat/jxl.h>
+#endif
+
+#ifdef use_jpg_library
+#include <xolatile/xormat/jpg.h>
+#endif
+
+#ifdef use_tga_library
+#include <xolatile/xormat/tga.h>
+#endif
+
+static void * format_image_import (const char * path, uint * width, uint * height) {
+       uint * data = null;
+
+#ifdef use_png_library
+       if (data == null) {
+               char buffer [256] = "";
+
+               if (file_exists (string_concatenate (string_copy (buffer, path), ".png")) == true) {
+                       data = png_image_import (buffer, width, height);
+               }
+       }
+#endif
+
+#ifdef use_jxl_library
+       if (data == null) {
+               char buffer [256] = "";
+
+               if (file_exists (string_concatenate (string_copy (buffer, path), ".jxl")) == true) {
+                       data = jxl_image_import (buffer, width, height);
+               }
+       }
+#endif
+
+#ifdef use_jpg_library
+       if (data == null) {
+               char buffer [256] = "";
+
+               if (file_exists (string_concatenate (string_copy (buffer, path), ".jpg")) == true) {
+                       data = jpg_image_import (buffer, width, height);
+               }
+       }
+#endif
+
+#ifdef use_tga_library
+       if (data == null) {
+               char buffer [256] = "";
+
+               if (file_exists (string_concatenate (string_copy (buffer, path), ".tga")) == true) {
+                       data = tga_image_import (buffer, width, height);
+               }
+       }
+#endif
+
+       if (data == null) {
+               switch (file_type (path)) {
+#ifdef use_png_library
+                       case (file_type_png_image): {
+                               if (file_exists (path) == true) {
+                                       data = png_image_import (path, width, height);
+                               } else {
+                                       print ("/w File '/3%s/-' doesn't exist.\n", path);
+                               }
+                       } break;
+#endif
+#ifdef use_jxl_library
+                       case (file_type_jxl_image): {
+                               if (file_exists (path) == true) {
+                                       data = jxl_image_import (path, width, height);
+                               } else {
+                                       print ("/w File '/3%s/-' doesn't exist.\n", path);
+                               }
+                       } break;
+#endif
+#ifdef use_jpg_library
+                       case (file_type_jpg_image): {
+                               if (file_exists (path) == true) {
+                                       data = jpg_image_import (path, width, height);
+                               } else {
+                                       print ("/w File '/3%s/-' doesn't exist.\n", path);
+                               }
+                       } break;
+#endif
+#ifdef use_tga_library
+                       case (file_type_tga_image): {
+                               if (file_exists (path) == true) {
+                                       data = tga_image_import (path, width, height);
+                               } else {
+                                       print ("/w File '/3%s/-' doesn't exist.\n", path);
+                               }
+                       } break;
+#endif
+                       default: {
+                               print ("/w File '/3%s/-' doesn't exist or file type isn't supported.\n", path);
+                       } break;
+               }
+       }
+
+       return (data);
+}
diff --git a/xormat/jxl.h b/xormat/jxl.h
new file mode 100644 (file)
index 0000000..91754ad
--- /dev/null
@@ -0,0 +1,68 @@
+#include <jxl/decode.h>
+
+#ifndef use_jxl_library
+#define use_jxl_library
+#endif
+
+static void * jxl_image_import (const char * path, uint * width, uint * height) {
+       JxlDecoder       * decoder     = null;
+       JxlBasicInfo       information = { 0 };
+       JxlPixelFormat     format      = { 4, JXL_TYPE_UINT8, JXL_NATIVE_ENDIAN, 0 };
+       JxlDecoderStatus   status      = JXL_DEC_ERROR;
+
+       fatal_failure (path   == null, "jxl_image_import: File path is null pointer.");
+       fatal_failure (width  == null, "jxl_image_import: Width is null pointer.");
+       fatal_failure (height == null, "jxl_image_import: Height is null pointer.");
+
+       ulong   size        = file_size   (path);
+       uchar * data        = file_record (path);
+       uint  * pixel_array = null;
+       ulong   output_size = 0;
+
+       decoder = JxlDecoderCreate (null);
+
+       fatal_failure (decoder == null, "jxl_image_import: Failed to create a decoder.");
+
+       status = JxlDecoderSubscribeEvents (decoder, JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE);
+
+       fatal_failure (status != JXL_DEC_SUCCESS, "jxl_image_import: Failed to subscribe decoder basic information and full image events.");
+
+       status = JxlDecoderSetInput (decoder, data, size);
+
+       fatal_failure (status != JXL_DEC_SUCCESS, "jxl_image_import: Failed to set decoder input data and size.");
+
+       for (status = JxlDecoderProcessInput (decoder); true; status = JxlDecoderProcessInput (decoder)) {
+               fatal_failure (status == JXL_DEC_ERROR,           "jxl_image_import: Decoder internal error.");
+               fatal_failure (status == JXL_DEC_NEED_MORE_INPUT, "jxl_image_import: Decoder needs more input data.");
+
+               if (status == JXL_DEC_BASIC_INFO) {
+                       status = JxlDecoderGetBasicInfo(decoder, &information);
+                       fatal_failure (status != JXL_DEC_SUCCESS, "jxl_image_import: Failed to get basic image information.");
+                       continue;
+               }
+
+               if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) {
+                       status = JxlDecoderImageOutBufferSize(decoder, & format, & output_size);
+                       fatal_failure (status != JXL_DEC_SUCCESS, "jxl_image_import: Failed to get image output buffer size.");
+                       if (pixel_array != null) {
+                               pixel_array = deallocate (pixel_array);
+                       }
+                       pixel_array = allocate (output_size);
+                       status = JxlDecoderSetImageOutBuffer(decoder, & format, pixel_array, output_size);
+                       fatal_failure (status != JXL_DEC_SUCCESS, "jxl_image_import: Failed to set image output buffer data.");
+                       continue;
+               }
+
+               if (status == JXL_DEC_FULL_IMAGE) continue;
+               if (status == JXL_DEC_SUCCESS)    break;
+       }
+
+       * width  = information.xsize;
+       * height = information.ysize;
+
+       JxlDecoderDestroy (decoder);
+
+       data = deallocate (data);
+
+       return (pixel_array);
+}
diff --git a/xormat/png.h b/xormat/png.h
new file mode 100644 (file)
index 0000000..e7b5bdb
--- /dev/null
@@ -0,0 +1,106 @@
+#include <stdio.h>
+#include <png.h>
+
+#ifndef use_png_library
+#define use_png_library
+#endif
+
+static void * png_image_import (const char * path, uint * width, uint * height) {
+       FILE * file;
+       uint * data;
+       uint   index;
+
+       png_byte    colour_type  = 0;
+       png_byte    bit_depth    = 0;
+       png_bytep * row_pointers = null;
+
+       png_structp structure   = null;
+       png_infop   information = null;
+
+       fatal_failure (path   == null, "png_image_import: File path is null pointer.");
+       fatal_failure (width  == null, "png_image_import: Width is null pointer.");
+       fatal_failure (height == null, "png_image_import: Height is null pointer.");
+
+       file = fopen (path, "rb");
+
+       fatal_failure (file == null, path);
+
+       structure   = png_create_read_struct (PNG_LIBPNG_VER_STRING, null, null, null);
+       information = png_create_info_struct (structure);
+
+       png_init_io   (structure, file);
+       png_read_info (structure, information);
+
+       * width       = png_get_image_width  (structure, information);
+       * height      = png_get_image_height (structure, information);
+         colour_type = png_get_color_type   (structure, information);
+         bit_depth   = png_get_bit_depth    (structure, information);
+
+       if (bit_depth == 16) {
+               png_set_strip_16 (structure);
+       }
+
+       if (colour_type == PNG_COLOR_TYPE_PALETTE) {
+               png_set_palette_to_rgb (structure);
+       }
+
+       if ((colour_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8)) {
+               png_set_expand_gray_1_2_4_to_8 (structure);
+       }
+
+       if (png_get_valid (structure, information, PNG_INFO_tRNS)) {
+               png_set_tRNS_to_alpha (structure);
+       }
+
+       if ((colour_type == PNG_COLOR_TYPE_RGB) || (colour_type == PNG_COLOR_TYPE_GRAY) || (colour_type == PNG_COLOR_TYPE_PALETTE)) {
+               png_set_filler (structure, 0xff, PNG_FILLER_AFTER);
+       }
+
+       if ((colour_type == PNG_COLOR_TYPE_GRAY) || (colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)) {
+               png_set_gray_to_rgb (structure);
+       }
+
+       png_read_update_info (structure, information);
+
+       row_pointers = allocate ((* height) * sizeof (* row_pointers));
+
+       for (index = 0; index < (* height); ++index) {
+               row_pointers [index] = allocate (png_get_rowbytes (structure, information));
+       }
+
+       png_read_image (structure, row_pointers);
+
+       fclose (file);
+
+       data = allocate ((* width) * (* height) * sizeof (* data));
+
+       for (index = 0; index < (* height); ++index) {
+               memory_copy (& data [index * (* width)], row_pointers [index], (* width) * sizeof (* data));
+
+               row_pointers [index] = deallocate (row_pointers [index]);
+       }
+
+       row_pointers = deallocate (row_pointers);
+
+       png_destroy_read_struct (& structure, & information, null);
+
+       return (data);
+}
+
+static void png_image_export (const char * path, uint * data, uint width, uint height) {
+       png_image image = { 0 };
+
+       fatal_failure (path   == null, "png_image_export: File path is null pointer.");
+       fatal_failure (data   == null, "png_image_export: Data is null pointer.");
+       fatal_failure (width  == 0,    "png_image_export: Width is equal to zero.");
+       fatal_failure (height == 0,    "png_image_export: Height is equal to zero.");
+
+       image.version = PNG_IMAGE_VERSION;
+       image.format  = PNG_FORMAT_RGBA;
+       image.width   = width;
+       image.height  = height;
+
+       png_image_write_to_file (& image, path, 0, data, 0, null);
+
+       png_image_free (& image);
+}
diff --git a/xpenal.h b/xpenal.h
new file mode 100755 (executable)
index 0000000..736b75b
--- /dev/null
+++ b/xpenal.h
@@ -0,0 +1,19 @@
+///                              _
+/// __  ___ __   ___ _ __   __ _| |
+/// \ \/ / '_ \ / _ \ '_ \ / _` | |
+///  >  <| |_) |  __/ | | | (_| | |
+/// /_/\_\ .__/ \___|_| |_|\__,_|_|
+///      |_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xpenal - Tiny and elegant OpenAL wrapper library so I don't go insane because of multithreading.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+PASTE THE SEMI-FINISHED CODE LATER...
diff --git a/xpengl.h b/xpengl.h
new file mode 100755 (executable)
index 0000000..125b6ca
--- /dev/null
+++ b/xpengl.h
@@ -0,0 +1,1209 @@
+///                              _
+/// __  ___ __   ___ _ __   __ _| |
+/// \ \/ / '_ \ / _ \ '_ \ / _` | |
+///  >  <| |_) |  __/ | | | (_| | |
+/// /_/\_\ .__/ \___|_| |_|\__, |_|
+///      |_|               |___/
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xpengl - Tiny and elegant OpenGL + GLFW wrapper library so I don't go insane because of Khronos.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+#include <GLFW/glfw3.h>
+
+#define opengl_font_width  (8)
+#define opengl_font_height (16)
+
+//~typedef enum {
+       //~opengl_window_fullscreen  = 0x1,
+       //~opengl_window_transparent = 0x2,
+       //~opengl_window_resizable   = 0x4,
+       //~opengl_window_decorated   = 0x8
+//~} opengl_window_flag;
+
+typedef struct {
+       GLFWwindow * window;
+
+       PFNGLGENVERTEXARRAYSPROC         glGenVertexArrays;
+       PFNGLBINDVERTEXARRAYPROC         glBindVertexArray;
+       PFNGLGENBUFFERSPROC              glGenBuffers;
+       PFNGLBINDBUFFERPROC              glBindBuffer;
+       PFNGLCREATESHADERPROC            glCreateShader;
+       PFNGLSHADERSOURCEPROC            glShaderSource;
+       PFNGLCOMPILESHADERPROC           glCompileShader;
+       PFNGLCREATEPROGRAMPROC           glCreateProgram;
+       PFNGLATTACHSHADERPROC            glAttachShader;
+       PFNGLBINDFRAGDATALOCATIONPROC    glBindFragDataLocation;
+       PFNGLLINKPROGRAMPROC             glLinkProgram;
+       PFNGLUSEPROGRAMPROC              glUseProgram;
+       PFNGLGETATTRIBLOCATIONPROC       glGetAttribLocation;
+       PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
+       PFNGLVERTEXATTRIBPOINTERPROC     glVertexAttribPointer;
+       PFNGLUNIFORM1IPROC               glUniform1i;
+       PFNGLDELETEVERTEXARRAYSPROC      glDeleteVertexArrays;
+       PFNGLDELETEBUFFERSPROC           glDeleteBuffers;
+       PFNGLDELETESHADERPROC            glDeleteShader;
+       PFNGLDELETEPROGRAMPROC           glDeleteProgram;
+       PFNGLGETUNIFORMLOCATIONPROC      glGetUniformLocation;
+       PFNGLBUFFERDATAPROC              glBufferData;
+
+       bool signal [signal_count];
+       bool cursor [cursor_count];
+       int  cursor_x;
+       int  cursor_y;
+
+       bool      using_precomputed_spritesheet;
+       ulong     spritesheet_size;
+       ulong     vertex_limit;
+       ulong     index_limit;
+       uint      gameplay_framerate;
+       uint      animation_framerate;
+       uint      tab_width;
+       uint      default_font;
+       bool      active;
+       uint      window_width;
+       uint      window_height;
+       float     pixel_width;
+       float     pixel_height;
+       uint      framerate;
+       ulong     frame_time;
+       ulong     frame_begin;
+       ulong     frame_end;
+       uint      global_tick;
+       uint      gameplay_tick;
+       uint      animation_tick;
+       bool      freeze_cursor;
+       bool      freeze_signal;
+       uint      vertex_object;
+       uint      vertex_buffer;
+       uint      index_buffer;
+       uint      vertex_shader;
+       uint      fragment_shader;
+       uint      shader_program;
+       uint      spritesheet;
+       uint      vertex_count;
+       uint      index_count;
+       float   * vertex_array;
+       uint    * index_array;
+       uint      sprite_count;
+       uint      font_count;
+       uint    * spritesheet_data;
+       uint  * * sprite_data;
+       uint    * sprite_width;
+       uint    * sprite_height;
+       float   * sprite_u;
+       float   * sprite_v;
+       uint  * * font_index;
+       uint  * * font_width;
+       uint  * * font_height;
+       char    * font_begin;
+       char    * font_end;
+} opengl_structure;
+
+static uint opengl_sprite_raw_import (opengl_structure * opengl, uint * data, uint width, uint height) {
+       fatal_failure (opengl->active == true, "opengl_sprite_raw_import: OpenGL renderer is already initialized.");
+       fatal_failure (data           == null, "opengl_sprite_raw_import: Data is null pointer.");
+       fatal_failure (width          == 0,    "opengl_sprite_raw_import: Font image width is zero.");
+       fatal_failure (height         == 0,    "opengl_sprite_raw_import: Font image height is zero.");
+
+       ++opengl->sprite_count;
+
+       opengl->sprite_data   = reallocate (opengl->sprite_data,   opengl->sprite_count * sizeof (* opengl->sprite_data));
+       opengl->sprite_width  = reallocate (opengl->sprite_width,  opengl->sprite_count * sizeof (* opengl->sprite_width));
+       opengl->sprite_height = reallocate (opengl->sprite_height, opengl->sprite_count * sizeof (* opengl->sprite_height));
+       opengl->sprite_u      = reallocate (opengl->sprite_u,      opengl->sprite_count * sizeof (* opengl->sprite_u));
+       opengl->sprite_v      = reallocate (opengl->sprite_v,      opengl->sprite_count * sizeof (* opengl->sprite_v));
+
+       opengl->sprite_data   [opengl->sprite_count - 1] = data;
+       opengl->sprite_width  [opengl->sprite_count - 1] = width;
+       opengl->sprite_height [opengl->sprite_count - 1] = height;
+       opengl->sprite_u      [opengl->sprite_count - 1] = 0;
+       opengl->sprite_v      [opengl->sprite_count - 1] = 0;
+
+       return (opengl->sprite_count - 1);
+}
+
+static uint opengl_font_raw_import (opengl_structure * opengl, uint * data, uint image_width, char begin, char end, uint empty) {
+       uint   pointer = 0;
+       uint   width   = 0;
+       uint   height  = 0;
+
+       fatal_failure (opengl->active == true, "opengl_font_raw_import: OpenGL renderer is already initialized.");
+       fatal_failure (data           == null, "opengl_font_raw_import: Data is null pointer.");
+       fatal_failure (image_width    == 0,    "opengl_font_raw_import: Font image width is zero.");
+       fatal_failure (begin          >= end,  "opengl_font_raw_import: Font character range is inverted.");
+
+       ++opengl->font_count;
+
+       opengl->font_index  = reallocate (opengl->font_index,  opengl->font_count * sizeof (* opengl->font_index));
+       opengl->font_width  = reallocate (opengl->font_width,  opengl->font_count * sizeof (* opengl->font_width));
+       opengl->font_height = reallocate (opengl->font_height, opengl->font_count * sizeof (* opengl->font_height));
+       opengl->font_begin  = reallocate (opengl->font_begin,  opengl->font_count * sizeof (* opengl->font_begin));
+       opengl->font_end    = reallocate (opengl->font_end,    opengl->font_count * sizeof (* opengl->font_end));
+
+       opengl->font_begin [opengl->font_count - 1] = begin;
+       opengl->font_end   [opengl->font_count - 1] = end;
+
+       opengl->font_index  [opengl->font_count - 1] = allocate ((ulong) (end - begin + 1) * sizeof (* * opengl->font_index));
+       opengl->font_width  [opengl->font_count - 1] = allocate ((ulong) (end - begin + 1) * sizeof (* * opengl->font_width));
+       opengl->font_height [opengl->font_count - 1] = allocate ((ulong) (end - begin + 1) * sizeof (* * opengl->font_height));
+
+       for (char index = begin; index <= end; ++index) {
+               for (          ; data [pointer]                        == empty; ++pointer);
+               for (width  = 0; data [pointer + width]                != empty; ++width);
+               for (height = 0; data [pointer + height * image_width] != empty; ++height);
+
+               uint * buffer = allocate (width * height * sizeof (* buffer));
+
+               for (uint y = 0; y < height; ++y) {
+                       for (uint x = 0; x < width; ++x) {
+                               buffer [y * width + x] = data [pointer + (y * image_width) + x];
+                       }
+               }
+
+               opengl->font_index  [opengl->font_count - 1] [index - begin] = opengl_sprite_raw_import (opengl, buffer, width, height);
+               opengl->font_width  [opengl->font_count - 1] [index - begin] = width;
+               opengl->font_height [opengl->font_count - 1] [index - begin] = height;
+
+               pointer += width;
+
+               for (; data [pointer] == empty; ++pointer);
+
+               if (pointer % image_width == 2) {
+                       pointer += height * image_width;
+               }
+       }
+
+       return (opengl->font_count - 1);
+}
+
+static uint opengl_sprite_import (opengl_structure * opengl, const char * path) {
+       uint   width  = 0;
+       uint   height = 0;
+       uint * data   = null;
+
+       char buffer [256] = "";
+
+       if (opengl->using_precomputed_spritesheet == true) {
+               return (++opengl->sprite_count - 1);
+       }
+
+#ifdef use_png_library
+       if (file_exists (string_concatenate (string_copy (buffer, path), ".png")) == true) {
+               data = png_image_import (buffer, & width, & height);
+       } else {
+               print ("/w File '/3%s/-' doesn't exist.\n", buffer);
+       }
+#endif
+
+#ifdef use_jxl_library
+       if ((data == null) && (file_exists (string_concatenate (string_copy (buffer, path), ".jxl")) == true)) {
+               data = jxl_image_import (buffer, & width, & height);
+       }
+#endif
+
+       fatal_failure (data == null, "opengl_sprite_import: Unsupported image format.");
+
+       return (opengl_sprite_raw_import (opengl, data, width, height));
+}
+
+static uint opengl_font_import (opengl_structure * opengl, const char * path, char begin, char end, uint colour) {
+       uint   width  = 0;
+       uint   height = 0;
+       uint   result = 0;
+       uint * data   = null;
+
+       char buffer [256] = "";
+
+       if (opengl->using_precomputed_spritesheet == true) {
+               for (char index = begin; index <= end; ++index) {
+                       opengl->font_index [opengl->font_count] [index - begin] = ++opengl->sprite_count - 1;
+               }
+
+               return (++opengl->font_count - 1);
+       }
+
+#ifdef use_png_library
+       if (file_exists (string_concatenate (string_copy (buffer, path), ".png")) == true) {
+               data = png_image_import (buffer, & width, & height);
+       } else {
+               print ("/w File '/3%s/-' doesn't exist.\n", buffer);
+       }
+#endif
+
+#ifdef use_jxl_library
+       if ((data == null) && (file_exists (string_concatenate (string_copy (buffer, path), ".jxl")) == true)) {
+               data = jxl_image_import (buffer, & width, & height);
+       }
+#endif
+
+       fatal_failure (data == null, "opengl_font_import: Unsupported image format.");
+
+       result = opengl_font_raw_import (opengl, data, width, begin, end, colour);
+
+       data = deallocate (data);
+
+       return (result);
+}
+
+static uint opengl_sprite_width (opengl_structure * opengl, uint sprite) {
+       return (opengl->sprite_width [sprite]);
+}
+
+static uint opengl_sprite_height (opengl_structure * opengl, uint sprite) {
+       return (opengl->sprite_height [sprite]);
+}
+
+static uint opengl_center_x (opengl_structure * opengl, uint size) {
+       return ((opengl->window_width - size) / 2);
+}
+
+static uint opengl_center_y (opengl_structure * opengl, uint size) {
+       return ((opengl->window_height - size) / 2);
+}
+
+static bool opengl_cursor_inside (opengl_structure * opengl, int x, int y, uint width, uint height) {
+       return ((opengl->cursor_x > x)               &&
+               (opengl->cursor_y > y)               &&
+               (opengl->cursor_x < x + (int) width) &&
+               (opengl->cursor_y < y + (int) height));
+}
+
+static bool opengl_cursor_left_click (opengl_structure * opengl, int x, int y, uint width, uint height) {
+       if (opengl->cursor [cursor_left] == true) {
+               opengl->freeze_cursor = true;
+
+               return (opengl_cursor_inside (opengl, x, y, width, height) == true);
+       }
+
+       return (false);
+}
+
+static bool opengl_cursor_right_click (opengl_structure * opengl, int x, int y, uint width, uint height) {
+       if (opengl->cursor [cursor_right]) {
+               opengl->freeze_cursor = true;
+
+               return (opengl_cursor_inside (opengl, x, y, width, height));
+       }
+
+       return (false);
+}
+
+static void opengl_import_spritesheet (opengl_structure * opengl, const char * data_file) {
+       int file = file_open (data_file, file_flag_read);
+
+       fatal_failure (opengl->active == true, "opengl_import_spritesheet: OpenGL renderer is already initialized.");
+
+       file_read (file, & opengl->spritesheet_size, sizeof (opengl->spritesheet_size));
+
+       file_read (file, & opengl->sprite_count, sizeof (opengl->sprite_count));
+
+       opengl->sprite_width  = allocate (opengl->sprite_count * sizeof (* opengl->sprite_width));
+       opengl->sprite_height = allocate (opengl->sprite_count * sizeof (* opengl->sprite_height));
+       opengl->sprite_u      = allocate (opengl->sprite_count * sizeof (* opengl->sprite_u));
+       opengl->sprite_v      = allocate (opengl->sprite_count * sizeof (* opengl->sprite_v));
+
+       file_read (file, opengl->sprite_width,  opengl->sprite_count * sizeof (* opengl->sprite_width));
+       file_read (file, opengl->sprite_height, opengl->sprite_count * sizeof (* opengl->sprite_height));
+       file_read (file, opengl->sprite_u,      opengl->sprite_count * sizeof (* opengl->sprite_u));
+       file_read (file, opengl->sprite_v,      opengl->sprite_count * sizeof (* opengl->sprite_v));
+
+       file_read (file, & opengl->font_count, sizeof (opengl->font_count));
+
+       opengl->font_index  = allocate (opengl->font_count * sizeof (* opengl->font_index));
+       opengl->font_width  = allocate (opengl->font_count * sizeof (* opengl->font_width));
+       opengl->font_height = allocate (opengl->font_count * sizeof (* opengl->font_height));
+       opengl->font_begin  = allocate (opengl->font_count * sizeof (* opengl->font_begin));
+       opengl->font_end    = allocate (opengl->font_count * sizeof (* opengl->font_end));
+
+       file_read (file, opengl->font_begin, opengl->font_count * sizeof (* opengl->font_begin));
+       file_read (file, opengl->font_end,   opengl->font_count * sizeof (* opengl->font_end));
+
+       for (uint index = 0; index < opengl->font_count; ++index) {
+               uint range = (uint) (opengl->font_end [index] - opengl->font_begin [index]) + 1;
+
+               opengl->font_index  [index] = allocate (range * sizeof (* * opengl->font_index));
+               opengl->font_width  [index] = allocate (range * sizeof (* * opengl->font_width));
+               opengl->font_height [index] = allocate (range * sizeof (* * opengl->font_height));
+
+               for (uint subindex = 0; subindex < range; ++subindex) {
+                       file_read (file, & opengl->font_index  [index] [subindex], sizeof (* * opengl->font_index));
+                       file_read (file, & opengl->font_width  [index] [subindex], sizeof (* * opengl->font_width));
+                       file_read (file, & opengl->font_height [index] [subindex], sizeof (* * opengl->font_height));
+               }
+       }
+
+       file = file_close (file);
+
+       opengl->sprite_count = 0;
+       opengl->font_count   = 0;
+}
+
+static void opengl_export_spritesheet (opengl_structure * opengl, const char * data_file) {
+       int file = file_open (data_file, file_flag_write | file_flag_create | file_flag_truncate);
+
+       fatal_failure (opengl->spritesheet_data == null, "opengl_export_spritesheet: OpenGL renderer can't access spritesheet data.");
+
+       file_write (file, & opengl->spritesheet_size, sizeof (opengl->spritesheet_size));
+
+       file_write (file, & opengl->sprite_count, sizeof (opengl->sprite_count));
+
+       file_write (file, opengl->sprite_width,  opengl->sprite_count * sizeof (* opengl->sprite_width));
+       file_write (file, opengl->sprite_height, opengl->sprite_count * sizeof (* opengl->sprite_height));
+       file_write (file, opengl->sprite_u,      opengl->sprite_count * sizeof (* opengl->sprite_u));
+       file_write (file, opengl->sprite_v,      opengl->sprite_count * sizeof (* opengl->sprite_v));
+
+       file_write (file, & opengl->font_count, sizeof (opengl->font_count));
+
+       file_write (file, opengl->font_begin, opengl->font_count * sizeof (* opengl->font_begin));
+       file_write (file, opengl->font_end,   opengl->font_count * sizeof (* opengl->font_end));
+
+       for (uint index = 0; index < opengl->font_count; ++index) {
+               for (uint subindex = 0; subindex < (uint) (opengl->font_end [index] - opengl->font_begin [index]) + 1; ++subindex) {
+                       file_write (file, & opengl->font_index  [index] [subindex], sizeof (* * opengl->font_index));
+                       file_write (file, & opengl->font_width  [index] [subindex], sizeof (* * opengl->font_width));
+                       file_write (file, & opengl->font_height [index] [subindex], sizeof (* * opengl->font_height));
+               }
+       }
+
+       file = file_close (file);
+
+       print ("/c Exported internal binary data of OpenGL spritesheet.");
+}
+
+static opengl_structure * opengl_initialize (uint gameplay_framerate, uint animation_framerate, bool use_precomputed_spritesheet,
+                                             uint maximum_quads_on_screen, uint spritesheet_side) {
+       opengl_structure * opengl = allocate (sizeof (* opengl));
+
+       opengl->using_precomputed_spritesheet = use_precomputed_spritesheet;
+
+       opengl->spritesheet_size    = spritesheet_side;
+       opengl->gameplay_framerate  = gameplay_framerate;
+       opengl->animation_framerate = animation_framerate;
+       opengl->vertex_limit        = maximum_quads_on_screen * 32;
+       opengl->index_limit         = maximum_quads_on_screen * 6;
+       opengl->tab_width           = 4;
+       opengl->default_font        = ~0u;
+
+       if (use_precomputed_spritesheet == true) {
+               print ("[/0Comment/-] Importing spritesheet image and information...\n");
+
+               opengl_import_spritesheet (opengl, "binary/spritesheet.bin");
+       }
+
+       print ("[/2Success/-] Initialized OpenGL renderer.\n");
+
+       return (opengl);
+}
+
+static opengl_structure * opengl_deinitialize (opengl_structure * opengl) {
+       opengl->active = false;
+
+       for (uint index = 0; index < opengl->font_count; ++index) {
+               opengl->font_index  [index] = deallocate (opengl->font_index  [index]);
+               opengl->font_width  [index] = deallocate (opengl->font_width  [index]);
+               opengl->font_height [index] = deallocate (opengl->font_height [index]);
+       }
+
+       opengl->font_index  = deallocate (opengl->font_index);
+       opengl->font_width  = deallocate (opengl->font_width);
+       opengl->font_height = deallocate (opengl->font_height);
+       opengl->font_begin  = deallocate (opengl->font_begin);
+       opengl->font_end    = deallocate (opengl->font_end);
+
+       opengl->sprite_width  = deallocate (opengl->sprite_width);
+       opengl->sprite_height = deallocate (opengl->sprite_height);
+       opengl->sprite_u      = deallocate (opengl->sprite_u);
+       opengl->sprite_v      = deallocate (opengl->sprite_v);
+
+       if (opengl->using_precomputed_spritesheet == false) {
+               opengl->spritesheet_data = deallocate (opengl->spritesheet_data);
+       }
+
+       opengl->vertex_array = deallocate (opengl->vertex_array);
+       opengl->index_array  = deallocate (opengl->index_array);
+
+       glDeleteTextures (1, & opengl->spritesheet);
+
+       opengl->glDeleteProgram (opengl->shader_program);
+       opengl->glDeleteShader  (opengl->fragment_shader);
+       opengl->glDeleteShader  (opengl->vertex_shader);
+
+       opengl->glDeleteBuffers      (1, & opengl->index_buffer);
+       opengl->glDeleteBuffers      (1, & opengl->vertex_buffer);
+       opengl->glDeleteVertexArrays (1, & opengl->vertex_object);
+
+       glfwDestroyWindow (opengl->window);
+
+       glfwTerminate ();
+
+       print ("[/2Success/-] Deinitialized OpenGL renderer.\n");
+
+       return (deallocate (opengl));
+}
+
+static void opengl_configure (opengl_structure * opengl, uint window_width, uint window_height, const char * window_title) {
+       const ulong font_bitmap [190] = {
+               0x0000000000000000, 0x0000000000000000, 0x0000101010101010, 0x1000101000000000, 0x0024242400000000, 0x0000000000000000,
+               0x00002424247e2424, 0x7e24242400000000, 0x0010107c9290907c, 0x1212927c10100000, 0x0000649468081010, 0x202c524c00000000,
+               0x000018242418304a, 0x4444443a00000000, 0x0010101000000000, 0x0000000000000000, 0x0000081020202020, 0x2020100800000000,
+               0x0000201008080808, 0x0808102000000000, 0x000000000024187e, 0x1824000000000000, 0x000000000010107c, 0x1010000000000000,
+               0x0000000000000000, 0x0000101020000000, 0x000000000000007e, 0x0000000000000000, 0x0000000000000000, 0x0000101000000000,
+               0x0000040408081010, 0x2020404000000000, 0x00003c4242464a52, 0x6242423c00000000, 0x0000081828080808, 0x0808083e00000000,
+               0x00003c4242020408, 0x1020407e00000000, 0x00003c4242021c02, 0x0242423c00000000, 0x000002060a122242, 0x7e02020200000000,
+               0x00007e4040407c02, 0x0202423c00000000, 0x00001c2040407c42, 0x4242423c00000000, 0x00007e0202040408, 0x0810101000000000,
+               0x00003c4242423c42, 0x4242423c00000000, 0x00003c424242423e, 0x0202043800000000, 0x0000000000101000, 0x0000101000000000,
+               0x0000000000101000, 0x0000101020000000, 0x0000000408102040, 0x2010080400000000, 0x00000000007e0000, 0x7e00000000000000,
+               0x0000004020100804, 0x0810204000000000, 0x00003c4242420408, 0x0800080800000000, 0x00007c829ea2a2a2, 0xa69a807e00000000,
+               0x00003c424242427e, 0x4242424200000000, 0x00007c4242427c42, 0x4242427c00000000, 0x00003c4242404040, 0x4042423c00000000,
+               0x0000784442424242, 0x4242447800000000, 0x00007e4040407840, 0x4040407e00000000, 0x00007e4040407840, 0x4040404000000000,
+               0x00003c424240404e, 0x4242423c00000000, 0x0000424242427e42, 0x4242424200000000, 0x0000381010101010, 0x1010103800000000,
+               0x00000e0404040404, 0x0444443800000000, 0x0000424448506060, 0x5048444200000000, 0x0000404040404040, 0x4040407e00000000,
+               0x000082c6aa929282, 0x8282828200000000, 0x000042424262524a, 0x4642424200000000, 0x00003c4242424242, 0x4242423c00000000,
+               0x00007c424242427c, 0x4040404000000000, 0x00003c4242424242, 0x42424a3c02000000, 0x00007c424242427c, 0x5048444200000000,
+               0x00003c4240403c02, 0x0242423c00000000, 0x0000fe1010101010, 0x1010101000000000, 0x0000424242424242, 0x4242423c00000000,
+               0x0000424242424224, 0x2424181800000000, 0x0000828282828292, 0x92aac68200000000, 0x0000424224241818, 0x2424424200000000,
+               0x0000828244442810, 0x1010101000000000, 0x00007e0202040810, 0x2040407e00000000, 0x0000382020202020, 0x2020203800000000,
+               0x0000404020201010, 0x0808040400000000, 0x0000380808080808, 0x0808083800000000, 0x0000102844000000, 0x0000000000000000,
+               0x0000000000000000, 0x0000007e00000000, 0x1008000000000000, 0x0000000000000000, 0x00000000003c023e, 0x4242423e00000000,
+               0x00004040407c4242, 0x4242427c00000000, 0x00000000003c4240, 0x4040423c00000000, 0x00000202023e4242, 0x4242423e00000000,
+               0x00000000003c4242, 0x7e40403c00000000, 0x00000e10107c1010, 0x1010101000000000, 0x00000000003e4242, 0x4242423e02023c00,
+               0x00004040407c4242, 0x4242424200000000, 0x0000101000301010, 0x1010103800000000, 0x00000404000c0404, 0x0404040444443800,
+               0x0000404040424448, 0x7048444200000000, 0x0000301010101010, 0x1010103800000000, 0x0000000000fc9292, 0x9292929200000000,
+               0x00000000007c4242, 0x4242424200000000, 0x00000000003c4242, 0x4242423c00000000, 0x00000000007c4242, 0x4242427c40404000,
+               0x00000000003e4242, 0x4242423e02020200, 0x00000000005e6040, 0x4040404000000000, 0x00000000003e4040, 0x3c02027c00000000,
+               0x00001010107c1010, 0x1010100e00000000, 0x0000000000424242, 0x4242423e00000000, 0x0000000000424242, 0x2424181800000000,
+               0x0000000000828292, 0x9292927c00000000, 0x0000000000424224, 0x1824424200000000, 0x0000000000424242, 0x4242423e02023c00,
+               0x00000000007e0408, 0x1020407e00000000, 0x00000c1010102010, 0x1010100c00000000, 0x0000101010101010, 0x1010101000000000,
+               0x0000300808080408, 0x0808083000000000, 0x000000000062928c, 0x0000000000000000
+       };
+
+       const char * vertex_shader =
+               "# version 330 core\n"
+               "in  vec2 vertex_xy;\n"
+               "in  vec2 vertex_uv;\n"
+               "in  vec4 vertex_rgba;\n"
+               "out vec2 fragment_uv;\n"
+               "out vec4 fragment_rgba;\n"
+               "void main () {\n"
+               "  gl_Position   = vec4 (vertex_xy, 0, 1);\n"
+               "  fragment_uv   = vertex_uv;\n"
+               "  fragment_rgba = vertex_rgba;\n"
+               "}\n";
+
+       const char * fragment_shader =
+               "# version 330 core\n"
+               "uniform sampler2D texture_p;\n"
+               "in  vec2 fragment_uv;\n"
+               "in  vec4 fragment_rgba;\n"
+               "out vec4 data;\n"
+               "void main () {\n"
+               "  data = texture (texture_p, fragment_uv) * fragment_rgba;\n"
+               "}\n";
+
+       uint * dumb_buffer = null;
+       uint * order       = null;
+
+       uint xy_attribute   = 0;
+       uint uv_attribute   = 0;
+       uint rgba_attribute = 0;
+       //~uint flags          = 0;
+
+       uint u = 0;
+       uint v = 0;
+
+       if (opengl->using_precomputed_spritesheet == true) {
+               for (uint index = 0; index < 95; ++index) {
+                       opengl->font_index [opengl->font_count] [index] = ++opengl->sprite_count - 1;
+               }
+
+               ++opengl->sprite_count;
+               ++opengl->font_count;
+
+               goto ignore_import;
+       }
+
+       dumb_buffer = allocate (256 * sizeof (* dumb_buffer));
+
+       for (uint index = 0; index < 256; ++index) {
+               dumb_buffer [index] = 0xffffffff;
+       }
+
+       ++opengl->font_count;
+
+       const uint current = opengl->font_count - 1;
+
+       opengl->font_index  = reallocate (opengl->font_index,  opengl->font_count * sizeof (* opengl->font_index));
+       opengl->font_width  = reallocate (opengl->font_width,  opengl->font_count * sizeof (* opengl->font_width));
+       opengl->font_height = reallocate (opengl->font_height, opengl->font_count * sizeof (* opengl->font_height));
+       opengl->font_begin  = reallocate (opengl->font_begin,  opengl->font_count * sizeof (* opengl->font_begin));
+       opengl->font_end    = reallocate (opengl->font_end,    opengl->font_count * sizeof (* opengl->font_end));
+
+       opengl->font_begin [opengl->font_count - 1] = ' ';
+       opengl->font_end   [opengl->font_count - 1] = '~';
+
+       opengl->font_index  [opengl->font_count - 1] = allocate (95 * sizeof (* * opengl->font_index));
+       opengl->font_width  [opengl->font_count - 1] = allocate (95 * sizeof (* * opengl->font_width));
+       opengl->font_height [opengl->font_count - 1] = allocate (95 * sizeof (* * opengl->font_height));
+
+       for (uint index = 0; index < 95; ++index) {
+               uint * buffer = allocate (opengl_font_width * opengl_font_height * sizeof (* buffer));
+
+               for (uint value = 0; value < 2; ++value) {
+                       for (uint bit = 64; bit > 0; --bit) {
+                               uint destination = ((value << 3) - ((bit - 1) >> 3) + 7) * opengl_font_width - ((bit - 1) & 7) + 7;
+                               uint source      = (font_bitmap [2 * index + value] >> (bit - 1)) & 1;
+
+                               buffer [destination] = (source) ? 0xffffffff : 0x00000000;
+                       }
+               }
+
+               opengl->font_index  [current] [index] = opengl_sprite_raw_import (opengl, buffer, opengl_font_width, opengl_font_height);
+               opengl->font_width  [current] [index] = opengl_font_width;
+               opengl->font_height [current] [index] = opengl_font_height;
+       }
+
+       opengl_sprite_raw_import (opengl, dumb_buffer, 16, 16);
+
+       opengl->spritesheet_data = allocate (opengl->spritesheet_size * opengl->spritesheet_size * sizeof (* opengl->spritesheet_data));
+
+       order = allocate (opengl->sprite_count * sizeof (* order));
+
+       for (uint index = 0; index < opengl->sprite_count; ++index) {
+               order [index] = index;
+       }
+
+       for (uint index = 0; index < opengl->sprite_count; ++index) {
+               for (uint subindex = 0; subindex < opengl->sprite_count; ++subindex) {
+                       if (opengl->sprite_height [order [index]] < opengl->sprite_height [order [subindex]]) {
+                               uint temporary = order [index];
+
+                               order [index]    = order [subindex];
+                               order [subindex] = temporary;
+                       }
+               }
+       }
+
+       for (uint index = 0; index < opengl->sprite_count; ++index) {
+               if (u + opengl->sprite_width [order [index]] >= opengl->spritesheet_size) {
+                       u *= 0;
+                       v += opengl->sprite_height [order [index]];
+               }
+
+               opengl->sprite_u [order [index]] = (float) u / (float) opengl->spritesheet_size;
+               opengl->sprite_v [order [index]] = (float) v / (float) opengl->spritesheet_size;
+
+               for (uint y = 0; y < opengl->sprite_height [order [index]]; ++y) {
+                       for (uint x = 0; x < opengl->sprite_width [order [index]]; ++x) {
+                               uint destination = (v + y) * opengl->spritesheet_size + (u + x);
+                               uint source      = y * opengl->sprite_width [order [index]] + x;
+
+                               opengl->spritesheet_data [destination] = opengl->sprite_data [order [index]] [source];
+                       }
+               }
+
+               u += opengl->sprite_width [order [index]];
+
+               opengl->sprite_data [order [index]] = deallocate (opengl->sprite_data [order [index]]);
+       }
+
+       opengl->sprite_data = deallocate (opengl->sprite_data);
+       order                  = deallocate (order);
+
+       ignore_import:
+
+       opengl->window_width  = window_width;
+       opengl->window_height = window_height;
+
+       opengl->pixel_width  = 2.0f / (float) window_width;
+       opengl->pixel_height = 2.0f / (float) window_height;
+
+       //~if (window_flags == 0) {
+               //~flags = opengl_window_decorated | opengl_window_resizable;
+       //~} else {
+               //~flags = window_flags;
+       //~}
+
+       glfwInit ();
+
+       glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR,   3);
+       glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR,   3);
+       glfwWindowHint (GLFW_OPENGL_PROFILE,          GLFW_OPENGL_CORE_PROFILE);
+       glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT,   1);
+
+       opengl->window = glfwCreateWindow ((int) window_width, (int) window_height, window_title, null, null);
+
+       glfwSetWindowSizeLimits (opengl->window, 320, 240, 1920, 1080);
+
+       fatal_failure (opengl->window == null, "Failed to create GLFW window.\n");
+
+       glfwMakeContextCurrent (opengl->window);
+
+       opengl->glGenVertexArrays         = (PFNGLGENVERTEXARRAYSPROC)         glfwGetProcAddress ("glGenVertexArrays");
+       opengl->glBindVertexArray         = (PFNGLBINDVERTEXARRAYPROC)         glfwGetProcAddress ("glBindVertexArray");
+       opengl->glGenBuffers              = (PFNGLGENBUFFERSPROC)              glfwGetProcAddress ("glGenBuffers");
+       opengl->glBindBuffer              = (PFNGLBINDBUFFERPROC)              glfwGetProcAddress ("glBindBuffer");
+       opengl->glCreateShader            = (PFNGLCREATESHADERPROC)            glfwGetProcAddress ("glCreateShader");
+       opengl->glShaderSource            = (PFNGLSHADERSOURCEPROC)            glfwGetProcAddress ("glShaderSource");
+       opengl->glCompileShader           = (PFNGLCOMPILESHADERPROC)           glfwGetProcAddress ("glCompileShader");
+       opengl->glCreateProgram           = (PFNGLCREATEPROGRAMPROC)           glfwGetProcAddress ("glCreateProgram");
+       opengl->glAttachShader            = (PFNGLATTACHSHADERPROC)            glfwGetProcAddress ("glAttachShader");
+       opengl->glBindFragDataLocation    = (PFNGLBINDFRAGDATALOCATIONPROC)    glfwGetProcAddress ("glBindFragDataLocation");
+       opengl->glLinkProgram             = (PFNGLLINKPROGRAMPROC)             glfwGetProcAddress ("glLinkProgram");
+       opengl->glUseProgram              = (PFNGLUSEPROGRAMPROC)              glfwGetProcAddress ("glUseProgram");
+       opengl->glGetAttribLocation       = (PFNGLGETATTRIBLOCATIONPROC)       glfwGetProcAddress ("glGetAttribLocation");
+       opengl->glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) glfwGetProcAddress ("glEnableVertexAttribArray");
+       opengl->glVertexAttribPointer     = (PFNGLVERTEXATTRIBPOINTERPROC)     glfwGetProcAddress ("glVertexAttribPointer");
+       opengl->glUniform1i               = (PFNGLUNIFORM1IPROC)               glfwGetProcAddress ("glUniform1i");
+       opengl->glDeleteVertexArrays      = (PFNGLDELETEVERTEXARRAYSPROC)      glfwGetProcAddress ("glDeleteVertexArrays");
+       opengl->glDeleteBuffers           = (PFNGLDELETEBUFFERSPROC)           glfwGetProcAddress ("glDeleteBuffers");
+       opengl->glDeleteShader            = (PFNGLDELETESHADERPROC)            glfwGetProcAddress ("glDeleteShader");
+       opengl->glDeleteProgram           = (PFNGLDELETEPROGRAMPROC)           glfwGetProcAddress ("glDeleteProgram");
+       opengl->glGetUniformLocation      = (PFNGLGETUNIFORMLOCATIONPROC)      glfwGetProcAddress ("glGetUniformLocation");
+       opengl->glBufferData              = (PFNGLBUFFERDATAPROC)              glfwGetProcAddress ("glBufferData");
+
+       glViewport (0, 0, (int) window_width, (int) window_height);
+
+       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+       glEnable (GL_CULL_FACE);
+       glEnable (GL_BLEND);
+
+       opengl->glGenVertexArrays (1, & opengl->vertex_object);
+       opengl->glBindVertexArray (opengl->vertex_object);
+
+       opengl->glGenBuffers (1, & opengl->vertex_buffer);
+       opengl->glBindBuffer (GL_ARRAY_BUFFER, opengl->vertex_buffer);
+
+       opengl->glGenBuffers (1, & opengl->index_buffer);
+       opengl->glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, opengl->index_buffer);
+
+       opengl->vertex_shader = opengl->glCreateShader (GL_VERTEX_SHADER);
+
+       opengl->glShaderSource  (opengl->vertex_shader, 1, & vertex_shader, null);
+       opengl->glCompileShader (opengl->vertex_shader);
+
+       opengl->fragment_shader = opengl->glCreateShader (GL_FRAGMENT_SHADER);
+
+       opengl->glShaderSource  (opengl->fragment_shader, 1, & fragment_shader, null);
+       opengl->glCompileShader (opengl->fragment_shader);
+
+       opengl->shader_program = opengl->glCreateProgram ();
+
+       opengl->glAttachShader (opengl->shader_program, opengl->vertex_shader);
+       opengl->glAttachShader (opengl->shader_program, opengl->fragment_shader);
+
+       opengl->glBindFragDataLocation (opengl->shader_program, 0, "data");
+
+       opengl->glLinkProgram (opengl->shader_program);
+       opengl->glUseProgram  (opengl->shader_program);
+
+       xy_attribute = (uint) opengl->glGetAttribLocation (opengl->shader_program, "vertex_xy");
+
+       opengl->glEnableVertexAttribArray (xy_attribute);
+
+       opengl->glVertexAttribPointer (xy_attribute, 2, GL_FLOAT, GL_FALSE, 8 * sizeof (float), (void *) 0);
+
+       uv_attribute = (uint) opengl->glGetAttribLocation (opengl->shader_program, "vertex_uv");
+
+       opengl->glEnableVertexAttribArray (uv_attribute);
+
+       opengl->glVertexAttribPointer (uv_attribute, 2, GL_FLOAT, GL_FALSE, 8 * sizeof (float), (void *) (2 * sizeof (float)));
+
+       rgba_attribute = (uint) opengl->glGetAttribLocation (opengl->shader_program, "vertex_rgba");
+
+       opengl->glEnableVertexAttribArray (rgba_attribute);
+
+       opengl->glVertexAttribPointer (rgba_attribute, 4, GL_FLOAT, GL_FALSE, 8 * sizeof (float), (void *) (4 * sizeof (float)));
+
+       opengl->vertex_array = allocate (opengl->vertex_limit * sizeof (opengl->vertex_array));
+       opengl->index_array  = allocate (opengl->index_limit  * sizeof (opengl->index_array));
+
+       glGenTextures (1, & opengl->spritesheet);
+
+       glBindTexture (GL_TEXTURE_2D, opengl->spritesheet);
+
+       glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, opengl->spritesheet_size, opengl->spritesheet_size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                     opengl->spritesheet_data);
+
+       opengl->glUniform1i (opengl->glGetUniformLocation (opengl->shader_program, "texture_p"), 0);
+
+       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_REPEAT);
+       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_REPEAT);
+       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+       if (opengl->using_precomputed_spritesheet == true) {
+               opengl->spritesheet_data = deallocate (opengl->spritesheet_data);
+       }
+
+       opengl->active = true;
+
+       opengl->frame_begin = nano_time ();
+
+       glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
+
+       glClear (GL_COLOR_BUFFER_BIT);
+
+       print ("[/2Success/-] Configured OpenGL renderer.\n");
+}
+
+static void opengl_synchronize (opengl_structure * opengl, uint colour) {
+       const int signal_code [signal_count] = {
+               0,
+               GLFW_KEY_A,                     GLFW_KEY_B,                     GLFW_KEY_C,                     GLFW_KEY_D,
+               GLFW_KEY_E,                     GLFW_KEY_F,                     GLFW_KEY_G,                     GLFW_KEY_H,
+               GLFW_KEY_I,                     GLFW_KEY_J,                     GLFW_KEY_K,                     GLFW_KEY_L,
+               GLFW_KEY_M,                     GLFW_KEY_N,                     GLFW_KEY_O,                     GLFW_KEY_P,
+               GLFW_KEY_Q,                     GLFW_KEY_R,                     GLFW_KEY_S,                     GLFW_KEY_T,
+               GLFW_KEY_U,                     GLFW_KEY_V,                     GLFW_KEY_W,                     GLFW_KEY_X,
+               GLFW_KEY_Y,                     GLFW_KEY_Z,                     GLFW_KEY_0,                     GLFW_KEY_1,
+               GLFW_KEY_2,                     GLFW_KEY_3,                     GLFW_KEY_4,                     GLFW_KEY_5,
+               GLFW_KEY_6,                     GLFW_KEY_7,                     GLFW_KEY_8,                     GLFW_KEY_9,
+               GLFW_KEY_ESCAPE,                GLFW_KEY_TAB,                   GLFW_KEY_ENTER,                 GLFW_KEY_ENTER,
+               GLFW_KEY_SLASH,                 GLFW_KEY_BACKSLASH,             GLFW_KEY_SEMICOLON,             GLFW_KEY_GRAVE_ACCENT,
+               GLFW_KEY_SPACE,                 GLFW_KEY_BACKSPACE,             GLFW_KEY_PERIOD,                GLFW_KEY_COMMA,
+               GLFW_KEY_APOSTROPHE,            GLFW_KEY_CAPS_LOCK,             GLFW_KEY_MINUS,                 GLFW_KEY_EQUAL,
+               GLFW_KEY_LEFT_BRACKET,          GLFW_KEY_RIGHT_BRACKET,         GLFW_KEY_LEFT_CONTROL,          GLFW_KEY_RIGHT_CONTROL,
+               GLFW_KEY_LEFT_SHIFT,            GLFW_KEY_RIGHT_SHIFT,           GLFW_KEY_LEFT_ALT,              GLFW_KEY_RIGHT_ALT,
+               GLFW_KEY_F1,                    GLFW_KEY_F2,                    GLFW_KEY_F3,                    GLFW_KEY_F4,
+               GLFW_KEY_F5,                    GLFW_KEY_F6,                    GLFW_KEY_F7,                    GLFW_KEY_F8,
+               GLFW_KEY_F9,                    GLFW_KEY_F10,                   GLFW_KEY_F11,                   GLFW_KEY_F12,
+               GLFW_KEY_UP,                    GLFW_KEY_DOWN,                  GLFW_KEY_LEFT,                  GLFW_KEY_RIGHT,
+               GLFW_KEY_NUM_LOCK,              GLFW_KEY_PAUSE,                 GLFW_KEY_INSERT,                GLFW_KEY_HOME,
+               GLFW_KEY_PAGE_UP,               GLFW_KEY_DELETE,                GLFW_KEY_END,                   GLFW_KEY_PAGE_DOWN,
+               GLFW_KEY_KP_ADD,                GLFW_KEY_KP_SUBTRACT,           GLFW_KEY_KP_MULTIPLY,           GLFW_KEY_KP_DIVIDE,
+               GLFW_KEY_KP_ENTER,              GLFW_KEY_KP_DECIMAL,            GLFW_KEY_KP_0,                  GLFW_KEY_KP_1,
+               GLFW_KEY_KP_2,                  GLFW_KEY_KP_3,                  GLFW_KEY_KP_4,                  GLFW_KEY_KP_5,
+               GLFW_KEY_KP_6,                  GLFW_KEY_KP_7,                  GLFW_KEY_KP_8,                  GLFW_KEY_KP_9
+       };
+
+       float r = (float) ((colour >> 24) & 0xff) / 255.0f;
+       float g = (float) ((colour >> 16) & 0xff) / 255.0f;
+       float b = (float) ((colour >>  8) & 0xff) / 255.0f;
+       float a = (float) ((colour >>  0) & 0xff) / 255.0f;
+
+       int new_window_width  = 0;
+       int new_window_height = 0;
+
+       glClearColor (r, g, b, a);
+
+       glClear (GL_COLOR_BUFFER_BIT);
+
+       glfwPollEvents ();
+
+       glfwSetWindowShouldClose (opengl->window, opengl->active == false);
+
+       glfwGetWindowSize (opengl->window, & new_window_width, & new_window_height);
+
+       if ((opengl->window_width != (uint) new_window_width) || (opengl->window_height != (uint) new_window_height)) {
+               if ((new_window_width <= 0) || (new_window_height <= 0)) return;
+
+               glViewport (0, 0, new_window_width, new_window_height);
+
+               opengl->window_width  = (uint) new_window_width;
+               opengl->window_height = (uint) new_window_height;
+
+               opengl->pixel_width  = 2.0f / (float) new_window_width;
+               opengl->pixel_height = 2.0f / (float) new_window_height;
+       }
+
+       opengl->cursor [cursor_left]   = (bool) (glfwGetMouseButton (opengl->window, GLFW_MOUSE_BUTTON_LEFT)   == GLFW_PRESS);
+       opengl->cursor [cursor_middle] = (bool) (glfwGetMouseButton (opengl->window, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
+       opengl->cursor [cursor_right]  = (bool) (glfwGetMouseButton (opengl->window, GLFW_MOUSE_BUTTON_RIGHT)  == GLFW_PRESS);
+
+       if (opengl->freeze_cursor == false) {
+               double x = 0.0;
+               double y = 0.0;
+
+               glfwGetCursorPos (opengl->window, & x, & y);
+
+               opengl->cursor_x = (int) x;
+               opengl->cursor_y = (int) y;
+
+               //~if ((opengl->cursor_x < 0) || (opengl->cursor_x > (int) opengl->window_width) ||
+                   //~(opengl->cursor_y < 0) || (opengl->cursor_y > (int) opengl->window_height)) {
+                       //~opengl->cursor_x = 0;
+                       //~opengl->cursor_y = 0;
+               //~}
+       } else {
+               if ((opengl->cursor [cursor_left]   == false)
+               &&  (opengl->cursor [cursor_middle] == false)
+               &&  (opengl->cursor [cursor_right]  == false)) {
+                       opengl->freeze_cursor = false;
+               }
+       }
+
+       if (opengl->freeze_signal == false) {
+               for (uint index = 0; index < signal_count; ++index) {
+                       opengl->signal [index] = (bool) (glfwGetKey (opengl->window, signal_code [index]) == GLFW_PRESS);
+               }
+       }
+
+       opengl->glBufferData (GL_ARRAY_BUFFER,         opengl->vertex_count * 4, opengl->vertex_array, GL_DYNAMIC_DRAW);
+       opengl->glBufferData (GL_ELEMENT_ARRAY_BUFFER, opengl->index_count  * 4, opengl->index_array,  GL_DYNAMIC_DRAW);
+
+       opengl->glBindBuffer (GL_ARRAY_BUFFER, opengl->vertex_buffer);
+
+       glDrawElements (GL_TRIANGLES, (int) opengl->index_count * 4, GL_UNSIGNED_INT, null);
+
+       glfwSwapBuffers (opengl->window);
+
+       opengl->vertex_count = 0;
+       opengl->index_count  = 0;
+
+       opengl->frame_end = nano_time ();
+
+       opengl->frame_time = opengl->frame_end - opengl->frame_begin;
+
+       if (opengl->frame_time < 1000000000ul / opengl->gameplay_framerate) {
+               nano_wait (1000000000ul / opengl->gameplay_framerate - opengl->frame_time);
+       }
+
+       if (opengl->global_tick % opengl->gameplay_framerate == 0) {
+               opengl->framerate = (uint) (1000000000ul / opengl->frame_time);
+       }
+
+       ++opengl->global_tick;
+
+       opengl->global_tick    = opengl->global_tick % (opengl->gameplay_framerate * opengl->animation_framerate);
+       opengl->gameplay_tick  = opengl->global_tick % (opengl->gameplay_framerate);
+       opengl->animation_tick = opengl->global_tick / (opengl->gameplay_framerate / opengl->animation_framerate);
+
+       opengl->frame_begin = nano_time ();
+}
+
+static void opengl_render_base (opengl_structure * opengl, uint sprite, int x, int y, uint u, uint v, uint width, uint height,
+                                float scale_x, float scale_y, int flip_x, int flip_y,
+                                uint colour_upper_left, uint colour_upper_right, uint colour_lower_left, uint colour_lower_right) {
+       float screen_x      = 0.0f;
+       float screen_y      = 0.0f;
+       float unwrap_x      = 0.0f;
+       float unwrap_y      = 0.0f;
+       float screen_width  = 0.0f;
+       float screen_height = 0.0f;
+       float unwrap_width  = 0.0f;
+       float unwrap_height = 0.0f;
+
+       if ((x > (int) opengl->window_width) || (y > (int) opengl->window_height)) return;
+
+       if ((x < (int) - ((float) width * scale_x)) || (y < (int) - ((float) height * scale_y))) return;
+
+       if (sprite                    >= opengl->sprite_count) return;
+       if (opengl->vertex_count + 32 >= opengl->vertex_limit)    return;
+       if (opengl->index_count  +  6 >= opengl->index_limit)     return;
+
+       screen_x = + ((float) x * opengl->pixel_width  - 1);
+       screen_y = - ((float) y * opengl->pixel_height - 1);
+
+       unwrap_x = opengl->sprite_u [sprite] + (float) u / (float) opengl->spritesheet_size;
+       unwrap_y = opengl->sprite_v [sprite] + (float) v / (float) opengl->spritesheet_size;
+
+       screen_width  = +((float) width  * opengl->pixel_width  * scale_x);
+       screen_height = -((float) height * opengl->pixel_height * scale_y);
+
+       unwrap_width  = (float) width  / (float) opengl->spritesheet_size;
+       unwrap_height = (float) height / (float) opengl->spritesheet_size;
+
+       opengl->vertex_array [opengl->vertex_count +  0] = screen_x;
+       opengl->vertex_array [opengl->vertex_count +  1] = screen_y;
+       opengl->vertex_array [opengl->vertex_count +  2] = unwrap_x + unwrap_width  * (float) (flip_y != 0);
+       opengl->vertex_array [opengl->vertex_count +  3] = unwrap_y + unwrap_height * (float) (flip_x != 0);
+       opengl->vertex_array [opengl->vertex_count +  4] = normal_r (colour_upper_left);
+       opengl->vertex_array [opengl->vertex_count +  5] = normal_g (colour_upper_left);
+       opengl->vertex_array [opengl->vertex_count +  6] = normal_b (colour_upper_left);
+       opengl->vertex_array [opengl->vertex_count +  7] = normal_a (colour_upper_left);
+
+       opengl->vertex_array [opengl->vertex_count +  8] = screen_x + screen_width;
+       opengl->vertex_array [opengl->vertex_count +  9] = screen_y;
+       opengl->vertex_array [opengl->vertex_count + 10] = unwrap_x + unwrap_width  * (float) (flip_y == 0);
+       opengl->vertex_array [opengl->vertex_count + 11] = unwrap_y + unwrap_height * (float) (flip_x != 0);
+       opengl->vertex_array [opengl->vertex_count + 12] = normal_r (colour_upper_right);
+       opengl->vertex_array [opengl->vertex_count + 13] = normal_g (colour_upper_right);
+       opengl->vertex_array [opengl->vertex_count + 14] = normal_b (colour_upper_right);
+       opengl->vertex_array [opengl->vertex_count + 15] = normal_a (colour_upper_right);
+
+       opengl->vertex_array [opengl->vertex_count + 16] = screen_x;
+       opengl->vertex_array [opengl->vertex_count + 17] = screen_y + screen_height;
+       opengl->vertex_array [opengl->vertex_count + 18] = unwrap_x + unwrap_width  * (float) (flip_y != 0);
+       opengl->vertex_array [opengl->vertex_count + 19] = unwrap_y + unwrap_height * (float) (flip_x == 0);
+       opengl->vertex_array [opengl->vertex_count + 20] = normal_r (colour_lower_left);
+       opengl->vertex_array [opengl->vertex_count + 21] = normal_g (colour_lower_left);
+       opengl->vertex_array [opengl->vertex_count + 22] = normal_b (colour_lower_left);
+       opengl->vertex_array [opengl->vertex_count + 23] = normal_a (colour_lower_left);
+
+       opengl->vertex_array [opengl->vertex_count + 24] = screen_x + screen_width;
+       opengl->vertex_array [opengl->vertex_count + 25] = screen_y + screen_height;
+       opengl->vertex_array [opengl->vertex_count + 26] = unwrap_x + unwrap_width  * (float) (flip_y == 0);
+       opengl->vertex_array [opengl->vertex_count + 27] = unwrap_y + unwrap_height * (float) (flip_x == 0);
+       opengl->vertex_array [opengl->vertex_count + 28] = normal_r (colour_lower_right);
+       opengl->vertex_array [opengl->vertex_count + 29] = normal_g (colour_lower_right);
+       opengl->vertex_array [opengl->vertex_count + 30] = normal_b (colour_lower_right);
+       opengl->vertex_array [opengl->vertex_count + 31] = normal_a (colour_lower_right);
+
+       opengl->index_array [opengl->index_count + 0] = (opengl->vertex_count >> 3) + 2;
+       opengl->index_array [opengl->index_count + 1] = (opengl->vertex_count >> 3) + 1;
+       opengl->index_array [opengl->index_count + 2] = (opengl->vertex_count >> 3) + 0;
+       opengl->index_array [opengl->index_count + 3] = (opengl->vertex_count >> 3) + 1;
+       opengl->index_array [opengl->index_count + 4] = (opengl->vertex_count >> 3) + 2;
+       opengl->index_array [opengl->index_count + 5] = (opengl->vertex_count >> 3) + 3;
+
+       opengl->vertex_count += 32;
+       opengl->index_count  +=  6;
+}
+
+static void opengl_render_rectangle (opengl_structure * opengl, int x, int y, uint width, uint height, uint colour) {
+       opengl_render_base (opengl, opengl->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16.0f, (float) height / 16.0f, 0, 0,
+                           colour, colour, colour, colour);
+}
+
+static void opengl_render_rectangle_vertical_gradient (opengl_structure * opengl, int x, int y, uint width, uint height,
+                                                       uint colour_up, uint colour_down) {
+       opengl_render_base (opengl, opengl->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16.0f, (float) height / 16.0f, 0, 0,
+                           colour_up, colour_up, colour_down, colour_down);
+}
+
+static void opengl_render_rectangle_horizontal_gradient (opengl_structure * opengl, int x, int y, uint width, uint height,
+                                                         uint colour_left, uint colour_right) {
+       opengl_render_base (opengl, opengl->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16.0f, (float) height / 16.0f, 0, 0,
+                           colour_left, colour_right, colour_left, colour_right);
+}
+
+static void opengl_render_sprite (opengl_structure * opengl, uint sprite, int x, int y) {
+       opengl_render_base (opengl, sprite, x, y, 0, 0, opengl->sprite_width [sprite], opengl->sprite_height [sprite], 1.0f, 1.0f, 0, 0,
+                           0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+}
+
+static void opengl_render_sprite_crop (opengl_structure * opengl, uint sprite, int x, int y, uint u, uint v, uint width, uint height) {
+       opengl_render_base (opengl, sprite, x, y, u, v, width, height, 1.0f, 1.0f, 0, 0, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+}
+
+static void opengl_render_sprite_flip (opengl_structure * opengl, uint sprite, int x, int y, int flip_x, int flip_y) {
+       opengl_render_base (opengl, sprite, x, y, 0, 0, opengl->sprite_width [sprite], opengl->sprite_height [sprite], 1.0f, 1.0f,
+                           flip_x, flip_y, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+}
+
+static void opengl_render_sprite_colour (opengl_structure * opengl, uint sprite, int x, int y, uint colour) {
+       opengl_render_base (opengl, sprite, x, y, 0, 0, opengl->sprite_width [sprite], opengl->sprite_height [sprite], 1.0f, 1.0f, 0, 0,
+                           colour, colour, colour, colour);
+}
+
+static void opengl_render_sprite_control (opengl_structure * opengl, uint sprite, int x, int y, uint u, uint v, uint width, uint height,
+                                          int flip_x, int flip_y) {
+       opengl_render_base (opengl, sprite, x, y, u, v, width, height, 1.0f, 1.0f, flip_x, flip_y, 0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+}
+
+static void opengl_render_sprite_crop_colour (opengl_structure * opengl, uint sprite, uint colour, int x, int y, uint u, uint v, uint width, uint height) {
+       opengl_render_base (opengl, sprite, x, y, u, v, width, height, 1.0f, 1.0f, 0, 0, colour, colour, colour, colour);
+}
+
+static void opengl_render_sprite_animate (opengl_structure * opengl, uint sprite, int x, int y, uint frames, uint state, uint states) {
+       uint width  = opengl->sprite_width  [sprite] / states;
+       uint height = opengl->sprite_height [sprite] / frames;
+       uint u      = width  * (state                   % states);
+       uint v      = height * (opengl->animation_tick  % frames);
+
+       opengl_render_sprite_crop (opengl, sprite, x, y, u, v, width, height);
+}
+
+static uint opengl_render_character_width (opengl_structure * opengl, char character, uint font, float scale) {
+       if ((character < opengl->font_begin [font]) || (character > opengl->font_end [font])) {
+               return (0);
+       } else {
+               const uint index = opengl->font_index [font] [character - opengl->font_begin [font]];
+
+               return ((uint) (scale * (float) opengl->sprite_width [index]));
+       }
+}
+
+static uint opengl_render_character_height (opengl_structure * opengl, char character, uint font, float scale) {
+       if ((character < opengl->font_begin [font]) || (character > opengl->font_end [font])) {
+               return (0);
+       } else {
+               const uint index = opengl->font_index [font] [character - opengl->font_begin [font]];
+
+               return ((uint) (scale * (float) opengl->sprite_height [index]));
+       }
+}
+
+static uint opengl_render_string_width (opengl_structure * opengl, const char * string, uint font, float scale) {
+       uint width = 0;
+       uint match = 0;
+
+       if (string == null) {
+               return (0);
+       }
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               if (string [index] == '\t') {
+                       width += opengl->tab_width * opengl_render_character_width (opengl, ' ', font, scale);
+               } else if (string [index] == '\n') {
+                       match = maximum (width, match);
+                       width = 0;
+               } else {
+                       width += opengl_render_character_width (opengl, string [index], font, scale);
+               }
+       }
+
+       return (maximum (width, match));
+}
+
+static uint opengl_render_string_height (opengl_structure * opengl, const char * string, uint font, float scale) {
+       uint height = opengl_render_character_height (opengl, ' ', font, scale);
+
+       if ((string == null) || (string [0] == '\0')) {
+               return (0);
+       }
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               if (string [index] == '\n') {
+                       height += opengl_render_character_height (opengl, ' ', font, scale);
+               }
+       }
+
+       return (height);
+}
+
+static void opengl_render_character_base (opengl_structure * opengl, char character, uint font, int x, int y, float scale,
+                                          uint colour_upper_left, uint colour_upper_right, uint colour_lower_left, uint colour_lower_right) {
+       if ((character < opengl->font_begin [font]) || (character > opengl->font_end [font])) return;
+
+       if (font == opengl->default_font) {
+               font = opengl->font_count - 1;
+       }
+
+       const uint index  = opengl->font_index    [font] [character - opengl->font_begin [font]];
+       const uint width  = opengl->sprite_width  [index];
+       const uint height = opengl->sprite_height [index];
+
+       opengl_render_base (opengl, index, x, y, 0, 0, width, height, scale, scale, 0, 0, colour_upper_left, colour_upper_right,
+                           colour_lower_left, colour_lower_right);
+}
+
+static void opengl_render_character (opengl_structure * opengl, char character, uint font, int x, int y, float scale, uint colour) {
+       opengl_render_character_base (opengl, character, font, x, y, scale, colour, colour, colour, colour);
+}
+
+static void opengl_render_character_vertical_gradient (opengl_structure * opengl, char character, uint font, int x, int y, float scale,
+                                                       uint colour_up, uint colour_down) {
+       opengl_render_character_base (opengl, character, font, x, y, scale, colour_up, colour_up, colour_down, colour_down);
+}
+
+static void opengl_render_character_horizontal_gradient (opengl_structure * opengl, char character, uint font, int x, int y, float scale,
+                                                         uint colour_left, uint colour_right) {
+       opengl_render_character_base (opengl, character, font, x, y, scale, colour_left, colour_right, colour_left, colour_right);
+}
+
+static void opengl_render_string_base (opengl_structure * opengl, const char * string, uint font, int x, int y, float scale,
+                                       uint colour_upper_left, uint colour_upper_right, uint colour_lower_left, uint colour_lower_right) {
+       int offset = x;
+
+       if (string == null) return;
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               if (string [index] == '\t') {
+                       x += opengl->tab_width * opengl_render_character_width (opengl, ' ', font, scale);
+                       continue;
+               } else if (string [index] == '\n') {
+                       x  = offset;
+                       y += opengl_render_character_height (opengl, ' ', font, scale);
+                       continue;
+               } else {
+                       opengl_render_character_base (opengl, string [index], font, x, y, scale, colour_upper_left, colour_upper_right,
+                                                     colour_lower_left, colour_lower_right);
+
+                       x += opengl_render_character_width (opengl, string [index], font, scale);
+               }
+       }
+}
+
+static void opengl_render_string (opengl_structure * opengl, const char * string, uint font, int x, int y, float scale, uint colour) {
+       opengl_render_string_base (opengl, string, font, x, y, scale, colour, colour, colour, colour);
+}
+
+static void opengl_render_string_vertical_gradient (opengl_structure * opengl, const char * string, uint font, int x, int y, float scale,
+                                                    uint colour_up, uint colour_down) {
+       opengl_render_string_base (opengl, string, font, x, y, scale, colour_up, colour_up, colour_down, colour_down);
+}
+
+static void opengl_render_string_horizontal_gradient (opengl_structure * opengl, const char * string, uint font, int x, int y, float scale,
+                                                      uint colour_left, uint colour_right) {
+       opengl_render_string_base (opengl, string, font, x, y, scale, colour_left, colour_right, colour_left, colour_right);
+}
+
+static void opengl_render_string_full_vertical_gradient (opengl_structure * opengl, const char * string, uint font, int x, int y, float scale,
+                                                         uint colour_up, uint colour_down) {
+       int  offset = x;
+       uint back   = 0;
+       uint up     = 0;
+       uint down   = 0;
+
+       const float interpolator = 1.0f / (float) string_full_height (string);
+
+       if (string == null) return;
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               if (string [index] == '\t') {
+                       x += opengl->tab_width * opengl_render_character_width (opengl, ' ', font, scale);
+                       continue;
+               } else if (string [index] == '\n') {
+                       back += 1;
+                       x     = offset;
+                       y    += opengl_render_character_height (opengl, ' ', font, scale);
+                       continue;
+               } else {
+                       up   = colour_linear_interpolation (colour_up, colour_down, (float) (back + 0) * interpolator);
+                       down = colour_linear_interpolation (colour_up, colour_down, (float) (back + 1) * interpolator);
+
+                       opengl_render_character_vertical_gradient (opengl, string [index], font, x, y, scale, up, down);
+
+                       x += opengl_render_character_width (opengl, string [index], font, scale);
+               }
+       }
+}
+
+static void opengl_render_string_full_horizontal_gradient (opengl_structure * opengl, const char * string, uint font, int x, int y, float scale,
+                                                           uint colour_left, uint colour_right) {
+       int  offset = x;
+       uint back   = 0;
+       uint left   = 0;
+       uint right  = 0;
+
+       const float interpolator = 1.0f / (float) string_full_width (string, opengl->tab_width);
+
+       if (string == null) return;
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               if (string [index] == '\t') {
+                       x += opengl->tab_width * opengl_render_character_width (opengl, ' ', font, scale);
+                       continue;
+               } else if (string [index] == '\n') {
+                       back  = 0;
+                       x     = offset;
+                       y    += opengl_render_character_height (opengl, ' ', font, scale);
+                       continue;
+               } else {
+                       back  += 1;
+                       left   = colour_linear_interpolation (colour_left, colour_right, (float) (back + 0) * interpolator);
+                       right  = colour_linear_interpolation (colour_left, colour_right, (float) (back + 1) * interpolator);
+
+                       opengl_render_character_horizontal_gradient (opengl, string [index], font, x, y, scale, left, right);
+
+                       x += opengl_render_character_width (opengl, string [index], font, scale);
+               }
+       }
+}
+
+static void opengl_render_framerate (opengl_structure * opengl, uint font, int x, int y, float scale, uint colour) {
+       opengl_render_string (opengl, number_to_string (opengl->framerate), font, x, y, scale, colour);
+}
+
+#undef opengl_font_width
+#undef opengl_font_height
diff --git a/xphere.h b/xphere.h
new file mode 100755 (executable)
index 0000000..813c8c5
--- /dev/null
+++ b/xphere.h
@@ -0,0 +1,86 @@
+///             _
+/// __  ___ __ | |__   ___ _ __ ___
+/// \ \/ / '_ \| '_ \ / _ \ '__/ _ \
+///  >  <| |_) | | | |  __/ | |  __/
+/// /_/\_\ .__/|_| |_|\___|_|  \___|
+///      |_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xphere - Spherical coordinate system header-only literally library for use in CPU-computed ray tracing...
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+typedef struct {
+       float distance;
+       float horizontal;
+       float vertical;
+} sphere_vector;
+
+static bool sphere_epsilon (float error) {
+       return (error < 0.000001);
+}
+
+static float sphere_distance (float x, float y, float z) {
+       return (square_root (x * x + y * y + z * z));
+}
+
+static float sphere_horizontal (float x, float z) {
+       return ((sphere_epsilon (z)) ? (sign (x) * pi / 2.0f) : (arc_tangent (x / z)));
+}
+
+static float sphere_vertical (float y, float z) {
+       return ((sphere_epsilon (z)) ? (sign (y) * pi / 2.0f) : (arc_tangent (y / z)));
+}
+
+static float sphere_x (float horizontal, float z) {
+       return (z * tangent (horizontal));
+}
+
+static float sphere_y (float vertical, float z) {
+       return (z * tangent (vertical));
+}
+
+static float sphere_z (float distance, float horizontal, float vertical) {
+       const float x_over_z = tangent (horizontal);
+       const float y_over_z = tangent (vertical);
+
+       return (distance * square_root (1.0f / (x_over_z * x_over_z + y_over_z * y_over_z + 1.0f)));
+}
+
+static void sphere_transpose_x (float * distance, float * horizontal, float x) {
+       const float origin = (* distance) * (* distance);
+       const float offset = x * x;
+       const float square = origin + offset + 2 * x * (* distance) * cosine (* horizontal);
+
+       * distance = square_root (square);
+
+       * horizontal = arc_sine ((square + offset - origin) / (2 * (* distance) * x));
+}
+
+static void sphere_transpose_y (float * distance, float * vertical, float y) {
+       const float origin = (* distance) * (* distance);
+       const float offset = y * y;
+
+       * distance = square_root (origin + offset + 2 * y * (* distance) * cosine (* vertical));
+}
+
+static void sphere_transpose_z (float * distance, float * horizontal, float * vertical, float z) {
+       const float origin = (* distance) * (* distance);
+       const float offset = z * z;
+       const float side_a = secant (* vertical);
+       const float side_b = tangent (* horizontal);
+
+       * distance = square_root (origin + offset + 2 * z * (* distance) * square_root (1.0f / (side_a * side_a + sibe_b * side_b)));
+}
+
+static void sphere_convert (sphere_vector * vector, float x, float y, float z) {
+       vector->distance   = sphere_distance   (x, y, z);
+       vector->horizontal = sphere_horizontal (x,    z);
+       vector->vertical   = sphere_vertical   (   y, z);
+}
diff --git a/xprite.h b/xprite.h
new file mode 100755 (executable)
index 0000000..8753a9e
--- /dev/null
+++ b/xprite.h
@@ -0,0 +1,131 @@
+///                  _ _
+/// __  ___ __  _ __(_) |_ ___
+/// \ \/ / '_ \| '__| | __/ _ \
+///  >  <| |_) | |  | | ||  __/
+/// /_/\_\ .__/|_|  |_|\__\___|
+///      |_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xprite - Custom file format for semi-efficient and very fast encoding and decoding of simple images.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+static unsigned int sprite_colour [128] = {
+       0x00000000,     0xff222222,     0xff444444,     0xff666666,     0xff888888,     0xffaaaaaa,     0xffcccccc,     0xffeeeeee,
+       0x11000000,     0xff000022,     0xff000044,     0xff000066,     0xff000088,     0xff0000aa,     0xff0000cc,     0xff0000ee,
+       0x22000000,     0xff002200,     0xff004400,     0xff006600,     0xff008800,     0xff00aa00,     0xff00cc00,     0xff00ee00,
+       0x33000000,     0xff220000,     0xff440000,     0xff660000,     0xff880000,     0xffaa0000,     0xffcc0000,     0xffee0000,
+       0x44000000,     0xff002222,     0xff004444,     0xff006666,     0xff008888,     0xff00aaaa,     0xff00cccc,     0xff00eeee,
+       0x55000000,     0xff222200,     0xff444400,     0xff666600,     0xff888800,     0xffaaaa00,     0xffcccc00,     0xffeeee00,
+       0x66000000,     0xff220022,     0xff440044,     0xff660066,     0xff880088,     0xffaa00aa,     0xffcc00cc,     0xffee00ee,
+       0x77000000,     0xff001122,     0xff002244,     0xff003366,     0xff004488,     0xff0055aa,     0xff0066cc,     0xff0077ee,
+       0x88000000,     0xff110022,     0xff220044,     0xff330066,     0xff440088,     0xff5500aa,     0xff6600cc,     0xff7700ee,
+       0x99000000,     0xff002211,     0xff004422,     0xff006633,     0xff008844,     0xff00aa55,     0xff00cc66,     0xff00ee77,
+       0xaa000000,     0xff112200,     0xff224400,     0xff336600,     0xff448800,     0xff55aa00,     0xff66cc00,     0xff77ee00,
+       0xbb000000,     0xff220011,     0xff440022,     0xff660033,     0xff880044,     0xffaa0055,     0xffcc0066,     0xffee0077,
+       0xcc000000,     0xff221100,     0xff442200,     0xff663300,     0xff884400,     0xffaa5500,     0xffcc6600,     0xffee7700,
+       0xdd000000,     0xff112222,     0xff224444,     0xff336666,     0xff448888,     0xff55aaaa,     0xff66cccc,     0xff77eeee,
+       0xee000000,     0xff222211,     0xff444422,     0xff666633,     0xff888844,     0xffaaaa55,     0xffcccc66,     0xffeeee77,
+       0xff000000,     0xff221122,     0xff442244,     0xff663366,     0xff884488,     0xffaa55aa,     0xffcc66cc,     0xffee77ee
+};
+
+static void * sprite_import (char * path, int * width, int * height) {
+       unsigned char check_width  = 0;
+       unsigned char check_height = 0;
+
+       int file, move;
+
+       unsigned int * data = null;
+
+       file = file_open (path, file_flag_read);
+
+       file_read (file, & check_width,  (int) sizeof (check_width));
+       file_read (file, & check_height, (int) sizeof (check_height));
+
+       * width  = (int) check_width;
+       * height = (int) check_height;
+
+       fatal_failure ((* width)  == 0, "sprite_import: Invalid sprite width.");
+       fatal_failure ((* height) == 0, "sprite_import: Invalid sprite height.");
+
+       data = allocate ((* width) * (* height) * (int) sizeof (* data));
+
+       for (move = 0; move < (* width) * (* height); ++move) {
+               int colour = 0;
+               int repeat = 0;
+
+               file_read (file, & colour, 1);
+
+               if ((colour & 0x80) == 0) {
+                       data [move] = sprite_colour [colour];
+               } else {
+                       int offset;
+
+                       file_read (file, & repeat, 1);
+
+                       colour &= 0x7f;
+                       repeat += 1;
+
+                       for (offset = 0; offset < repeat; ++offset) {
+                               data [move + offset] = sprite_colour [colour];
+                       }
+
+                       move += repeat - 1;
+               }
+       }
+
+       file = file_close (file);
+
+       return (data);
+}
+
+static void sprite_export (const char * path, int width, int height, unsigned int * data) {
+       int file, move;
+
+       file = file_open (path, file_flag_edit | file_flag_truncate | file_flag_create);
+
+       fatal_failure ((width  <= 0) || (width  >= 256), "sprite_export: Invalid sprite width.");
+       fatal_failure ((height <= 0) || (height >= 256), "sprite_export: Invalid sprite height.");
+
+       file_write (file, & width,  1);
+       file_write (file, & height, 1);
+
+       for (move = 0; move < width * height; ++move) {
+               int colour = 0;
+               int repeat = 0;
+
+               for (repeat = 1; (move + repeat < width * height) && (data [move] == data [move + repeat]) && (repeat < 256); ++repeat);
+
+               for (colour = 0; (data [move] != sprite_colour [colour]) && (colour < 128); ++colour);
+
+               if (colour == 128) colour = 127;
+
+               if (repeat == 1) {
+                       file_write (file, & colour, 1);
+               } else {
+                       colour |= 0x80;
+                       repeat -= 1;
+                       move   += repeat;
+
+                       file_write (file, & colour, 1);
+                       file_write (file, & repeat, 1);
+
+               }
+       }
+
+       file = file_close (file);
+}
+
+static void sprite_swap_channels (unsigned int * data, int width, int height) {
+       int move;
+
+       for (move = 0; move < width * height; ++move) {
+               data [move] = (data [move] & 0xff00ff00) | ((data [move] & 0xff0000) >> 16) | ((data [move] & 0xff) << 16);
+       }
+}
diff --git a/xrocessor.h b/xrocessor.h
new file mode 100755 (executable)
index 0000000..6b606b1
--- /dev/null
@@ -0,0 +1,303 @@
+/// __  ___ __ ___   ___ ___  ___ ___  ___  _ __
+/// \ \/ / '__/ _ \ / __/ _ \/ __/ __|/ _ \| '__|
+///  >  <| | | (_) | (_|  __/\__ \__ \ (_) | |
+/// /_/\_\_|  \___/ \___\___||___/___/\___/|_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xrocessor - Probably the most minimalistic general preprocessor aimed at Ada, Pascal and EAXHLA language syntax.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+//~#define token_limit (32)
+
+//~#include <xolatile/xtandard.h>
+//~#include <xolatile/xrena.h>
+
+static int  parse_comment (const char * buffer);
+static int  parse_include (const char * buffer);
+static int  parse_use     (const char * buffer);
+static int  parse_alias   (const char * buffer);
+static int  parse_macro   (const char * buffer);
+static int  parse_scope   (const char * buffer);
+static int  parse_unscope (const char * buffer);
+static int  parse_default (const char * buffer);
+static void parse_buffer  (const char * buffer, int limit);
+
+enum {
+       token_comment,  token_include,  token_use,      token_alias,    token_macro,    token_scope,    token_unscope,  token_default
+};
+
+static const char * token_key [token_default] = {
+       "---",          "include ",     "use ",         "alias ",       "macro ",       "scope ",       "unscope "
+};
+
+static int (* parse_key [token_default + 1]) (const char * buffer) = {
+       parse_comment,  parse_include,  parse_use,      parse_alias,    parse_macro,    parse_scope,    parse_unscope,  parse_default
+};
+
+static int token_count = 0;
+
+static struct {
+       const char * data;
+       int          size;
+       int          type;
+} * token_array [token_limit],
+  * token_value [token_limit];
+
+static int parse_default (const char * buffer) {
+       int select;
+
+       for (select = 0; select < token_count; ++select) {
+               if (string_compare_limit (buffer, token_array [select]->data, token_array [select]->size) == true) {
+                       if (token_array [select]->type == token_alias) {
+                               if (character_is_separator (buffer [-1])                         == false) continue;
+                               if (character_is_separator (buffer [token_array [select]->size]) == false) continue;
+
+                               output (token_value [select]->data, token_value [select]->size);
+
+                               return (token_array [select]->size);
+                       }
+
+                       if (token_array [select]->type == token_macro) {
+                               if (character_is_separator (buffer [-1])                         == false) continue;
+                               if (character_is_separator (buffer [token_array [select]->size]) == false) continue;
+
+                               parse_buffer (token_value [select]->data, token_value [select]->size);
+
+                               return (token_array [select]->size);
+                       }
+               }
+       }
+
+       output (buffer, 1);
+
+       return (1);
+}
+
+static int parse_comment (const char * buffer) {
+       int offset;
+
+       for (offset = 3; buffer [offset] != '\0'; ++offset) {
+               if (buffer [offset] == '\n') break;
+       }
+
+       return (offset + 1);
+}
+
+static int parse_use (const char * buffer) {
+       int offset;
+       int length;
+
+       for (offset = 4; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
+
+       ++token_count;
+
+       token_array [token_count - 1] = arena_add (sizeof (* * token_array));
+
+       token_array [token_count - 1]->data = & buffer [offset];
+       token_array [token_count - 1]->type = token_use;
+
+       for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
+
+       token_array [token_count - 1]->size = length;
+
+       return (offset + length + 1);
+}
+
+static int parse_include (const char * buffer) {
+       int    length;
+       int    offset;
+       char * data;
+
+       for (offset = 8; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
+
+       fatal_failure (buffer [offset] != '"', "parse_include: Not a string.");
+
+       ++token_count;
+
+       token_array [token_count - 1] = arena_add (sizeof (* * token_array));
+
+       token_array [token_count - 1]->data = & buffer [offset + 1];
+       token_array [token_count - 1]->type = token_include;
+
+       for (length = 1; (buffer [offset + length] != '\0') && (buffer [offset + length] != '"'); ++length);
+
+       token_array [token_count - 1]->size = length - 1;
+
+       data = arena_add_file (token_array [token_count - 1]->data, token_array [token_count - 1]->size);
+
+       parse_buffer (data, -1);
+
+       return (offset + length + 1);
+}
+
+static int parse_alias (const char * buffer) {
+       int offset;
+       int length;
+
+       for (offset = 6; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
+
+       ++token_count;
+
+       token_array [token_count - 1] = arena_add (sizeof (* * token_array));
+       token_value [token_count - 1] = arena_add (sizeof (* * token_value));
+
+       token_array [token_count - 1]->data = & buffer [offset];
+       token_array [token_count - 1]->type = token_alias;
+
+       for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
+
+       token_array [token_count - 1]->size = length;
+
+       for (offset += length; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
+
+       token_value [token_count - 1]->data = & buffer [offset];
+       token_value [token_count - 1]->type = token_alias;
+
+       for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
+
+       token_value [token_count - 1]->size = length;
+
+       return (offset + length + 1);
+}
+
+static int parse_macro (const char * buffer) {
+       int offset;
+       int length;
+
+       for (offset = 6; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
+
+       ++token_count;
+
+       token_array [token_count - 1] = arena_add (sizeof (* * token_array));
+       token_value [token_count - 1] = arena_add (sizeof (* * token_value));
+
+       token_array [token_count - 1]->data = & buffer [offset];
+       token_array [token_count - 1]->type = token_macro;
+
+       for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
+
+       token_array [token_count - 1]->size = length;
+
+       for (offset += length; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
+
+       token_value [token_count - 1]->data = & buffer [offset];
+       token_value [token_count - 1]->type = token_macro;
+
+       for (length = 0; buffer [offset + length] != '\0'; ++length) {
+               if (string_compare_limit (& buffer [offset + length], "end macro", 9) == true) {
+                       break;
+               }
+       }
+
+       token_value [token_count - 1]->size = length;
+
+       return (offset + length + 9 + 1);
+}
+
+static int parse_scope (const char * buffer) {
+       int offset;
+       int length;
+       int select;
+
+       for (offset = 6; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
+
+       for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
+
+       for (select = 0; select < token_count; ++select) {
+               if ((string_compare_limit (token_array [select]->data, & buffer [offset], length) == true) && (token_array [select]->type == token_use)) {
+                       for (; buffer [offset + length] != '\0'; ++length) {
+                               if (string_compare_limit (& buffer [offset + length], "end scope", 9) == true) {
+                                       return (offset + length + 9 + 1);
+                               }
+                       }
+               }
+       }
+
+       return (offset + length + 1);
+}
+
+static int parse_unscope (const char * buffer) {
+       int offset;
+       int length;
+       int select;
+
+       for (offset = 8; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
+
+       for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
+
+       for (select = 0; select < token_count; ++select) {
+               if ((string_compare_limit (token_array [select]->data, & buffer [offset], length) == true) && (token_array [select]->type == token_use)) {
+                       return (offset + length + 1);
+               }
+       }
+
+       for (; buffer [offset + length] != '\0'; ++length) {
+               if (string_compare_limit (& buffer [offset + length], "end unscope", 11) == true) {
+                       return (offset + length + 11 + 1);
+               }
+       }
+
+       return (offset + length + 1);
+}
+
+static void parse_buffer (const char * buffer, int limit) {
+       int offset;
+       int length;
+       int select;
+
+       for (length = offset = 0; (buffer [offset] != '\0') && (offset != limit); offset += length) {
+               for (select = 0; select < token_default; ++select) {
+                       length = string_length (token_key [select]);
+                       if (string_compare_limit (& buffer [offset], token_key [select], length) == true) {
+                               break;
+                       }
+               }
+
+               if (string_compare_limit (& buffer [offset], "end macro", 9) == true) {
+                       length = 9;
+                       continue;
+               }
+
+               if (string_compare_limit (& buffer [offset], "end scope", 9) == true) {
+                       length = 9;
+                       continue;
+               }
+
+               if (string_compare_limit (& buffer [offset], "end unscope", 11) == true) {
+                       length = 11;
+                       continue;
+               }
+
+               length = parse_key [select] (& buffer [offset]);
+       }
+}
+
+//~int main (int argc, char * * argv) {
+       //~int offset;
+       //~char * buffer;
+
+       //~if (argc != 2) return (2);
+
+       //~buffer = arena_add_file (argv [1], string_length (argv [1]));
+
+       //~parse_buffer (buffer, -1);
+
+       //~for (offset = 0; offset < token_count; ++offset) {
+               //~print ("/6entity %s:: %i == ", token_key [token_array [offset]->type], token_array [offset]->size);
+               //~output (token_array [offset]->data, token_array [offset]->size);
+               //~if ((token_array [offset]->type == token_alias) || (token_array [offset]->type == token_macro)) {
+                       //~print (" -> ");
+                       //~output (token_value [offset]->data, token_value [offset]->size);
+               //~}
+               //~print ("/-\n");
+       //~}
+
+       //~return (log_success);
+//~}
diff --git a/xross.h b/xross.h
new file mode 100755 (executable)
index 0000000..c23ad6d
--- /dev/null
+++ b/xross.h
@@ -0,0 +1,190 @@
+/// __  ___ __ ___  ___ ___
+/// \ \/ / '__/ _ \/ __/ __|
+///  >  <| | | (_) \__ \__ \
+/// /_/\_\_|  \___/|___/___/
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xross - Even I don't know what this is, my suggestion is to never use it...
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+typedef enum {
+       cross_window_fullscreen  = 0x1,
+       cross_window_transparent = 0x2,
+       cross_window_resizable   = 0x4,
+       cross_window_decorated   = 0x8
+} cross_window_flag;
+
+#ifdef use_raptor_renderer
+
+#define cross_structure                   raptor_structure
+#define cross_initialize                  raptor_initialize
+#define cross_deinitialize                raptor_deinitialize
+#define cross_sprite_raw_import           raptor_sprite_raw_import
+#define cross_font_raw_import             raptor_font_raw_import
+#define cross_sprite_import               raptor_sprite_import
+#define cross_font_import                 raptor_font_import
+#define cross_sprite_width                raptor_sprite_width
+#define cross_sprite_height               raptor_sprite_height
+#define cross_character_width             raptor_character_width
+#define cross_character_height            raptor_character_height
+#define cross_string_width                raptor_string_width
+#define cross_string_height               raptor_string_height
+#define cross_center_x                    raptor_center_x
+#define cross_center_y                    raptor_center_y
+#define cross_cursor_inside               raptor_cursor_inside
+#define cross_cursor_left_click           raptor_cursor_left_click
+#define cross_cursor_right_click          raptor_cursor_right_click
+#define cross_configure                   raptor_configure
+#define cross_render_base                 raptor_render_base
+#define cross_render_rectangle            raptor_render_rectangle
+#define cross_render_sprite               raptor_render_sprite
+#define cross_render_sprite_scale         raptor_render_sprite_scale
+#define cross_render_sprite_crop          raptor_render_sprite_crop
+#define cross_render_sprite_colour        raptor_render_sprite_colour
+#define cross_render_sprite_crop_colour   raptor_render_sprite_crop_colour
+#define cross_render_sprite_flip          raptor_render_sprite_flip
+#define cross_render_sprite_animate       raptor_render_sprite_animate
+#define cross_render_character            raptor_render_character
+#define cross_render_string               raptor_render_string
+#define cross_render_framerate            raptor_render_framerate
+#define cross_synchronize                 raptor_synchronize
+#define cross_render_rectangle_vertical_gradient raptor_render_rectangle_vertical_gradient
+
+#include "xaptor.h"
+
+#endif
+
+#ifdef use_common_renderer
+
+#define cross_structure                   common_structure
+#define cross_font_width                  common_font_width
+#define cross_font_height                 common_font_height
+#define cross_font_tabulator              common_font_tabulator
+#define cross_gameplay_framerate          common_gameplay_framerate
+#define cross_animation_framerate         common_animation_framerate
+#define cross_center_x                    common_center_x
+#define cross_center_y                    common_center_y
+#define cross_cursor_inside               common_cursor_inside
+#define cross_cursor_left_click           common_cursor_left_click
+#define cross_cursor_right_click          common_cursor_right_click
+#define cross_sprite_raw_import           common_sprite_raw_import
+#define cross_font_raw_import             common_font_raw_import
+#define cross_sprite_import               common_sprite_import
+#define cross_font_import                 common_font_import
+#define cross_sprite_width                common_sprite_width
+#define cross_sprite_height               common_sprite_height
+#define cross_initialize                  common_initialize
+#define cross_deinitialize                common_deinitialize
+#define cross_configure                   common_configure
+#define cross_synchronize                 common_synchronize
+#define cross_render_base                 common_render_base
+#define cross_render_rectangle            common_render_rectangle
+#define cross_render_rectangle_gradient_v common_render_rectangle_gradient_v
+#define cross_render_rectangle_gradient_h common_render_rectangle_gradient_h
+#define cross_render_sprite               common_render_sprite
+#define cross_render_sprite_crop          common_render_sprite_crop
+#define cross_render_sprite_colour        common_render_sprite_colour
+#define cross_render_sprite_crop_colour   common_render_sprite_crop_colour
+#define cross_render_sprite_flip          common_render_sprite_flip
+#define cross_render_sprite_animate       common_render_sprite_animate
+#define cross_render_sprite_preview       common_render_sprite_preview
+#define cross_render_sprite_control       common_render_sprite_control
+#define cross_render_string_width         common_render_string_width
+#define cross_render_string               common_render_string
+
+#include "xommon.h"
+
+#endif
+
+#ifdef use_opengl_renderer
+
+#define cross_structure                   opengl_structure
+#define cross_font_width                  opengl_font_width
+#define cross_font_height                 opengl_font_height
+#define cross_font_tabulator              opengl_font_tabulator
+#define cross_gameplay_framerate          opengl_gameplay_framerate
+#define cross_animation_framerate         opengl_animation_framerate
+#define cross_center_x                    opengl_center_x
+#define cross_center_y                    opengl_center_y
+#define cross_cursor_inside               opengl_cursor_inside
+#define cross_cursor_left_click           opengl_cursor_left_click
+#define cross_cursor_right_click          opengl_cursor_right_click
+#define cross_sprite_raw_import            opengl_sprite_raw_import
+#define cross_font_raw_import              opengl_font_raw_import
+#define cross_sprite_import               opengl_sprite_import
+#define cross_font_import                 opengl_font_import
+#define cross_sprite_width                opengl_sprite_width
+#define cross_sprite_height               opengl_sprite_height
+#define cross_initialize                  opengl_initialize
+#define cross_deinitialize                opengl_deinitialize
+#define cross_configure                   opengl_configure
+#define cross_synchronize                 opengl_synchronize
+#define cross_render_base                 opengl_render_base
+#define cross_render_rectangle            opengl_render_rectangle
+#define cross_render_rectangle_gradient_v opengl_render_rectangle_gradient_v
+#define cross_render_rectangle_gradient_h opengl_render_rectangle_gradient_h
+#define cross_render_sprite               opengl_render_sprite
+#define cross_render_sprite_crop          opengl_render_sprite_crop
+#define cross_render_sprite_colour        opengl_render_sprite_colour
+#define cross_render_sprite_crop_colour   opengl_render_sprite_crop_colour
+#define cross_render_sprite_flip          opengl_render_sprite_flip
+#define cross_render_sprite_animate       opengl_render_sprite_animate
+#define cross_render_sprite_preview       opengl_render_sprite_preview
+#define cross_render_sprite_control       opengl_render_sprite_control
+#define cross_render_character            opengl_render_character
+#define cross_render_string_width         opengl_render_string_width
+#define cross_render_string               opengl_render_string
+
+#include "xpengl.h"
+
+#endif
+
+#ifdef use_vulkan_renderer
+
+#define cross_structure                   vulkan_structure
+#define cross_font_width                  vulkan_font_width
+#define cross_font_height                 vulkan_font_height
+#define cross_font_tabulator              vulkan_font_tabulator
+#define cross_gameplay_framerate          vulkan_gameplay_framerate
+#define cross_animation_framerate         vulkan_animation_framerate
+#define cross_center_x                    vulkan_center_x
+#define cross_center_y                    vulkan_center_y
+#define cross_cursor_inside               vulkan_cursor_inside
+#define cross_cursor_left_click           vulkan_cursor_left_click
+#define cross_cursor_right_click          vulkan_cursor_right_click
+#define cross_sprite_raw_import            vulkan_sprite_raw_import
+#define cross_font_raw_import              vulkan_font_raw_import
+#define cross_sprite_import               vulkan_sprite_import
+#define cross_font_import                 vulkan_font_import
+#define cross_sprite_width                vulkan_sprite_width
+#define cross_sprite_height               vulkan_sprite_height
+#define cross_initialize                  vulkan_initialize
+#define cross_deinitialize                vulkan_deinitialize
+#define cross_configure                   vulkan_configure
+#define cross_synchronize                 vulkan_synchronize
+#define cross_render_base                 vulkan_render_base
+#define cross_render_rectangle            vulkan_render_rectangle
+#define cross_render_rectangle_gradient_v vulkan_render_rectangle_gradient_v
+#define cross_render_rectangle_gradient_h vulkan_render_rectangle_gradient_h
+#define cross_render_sprite               vulkan_render_sprite
+#define cross_render_sprite_crop          vulkan_render_sprite_crop
+#define cross_render_sprite_colour        vulkan_render_sprite_colour
+#define cross_render_sprite_crop_colour   vulkan_render_sprite_crop_colour
+#define cross_render_sprite_flip          vulkan_render_sprite_flip
+#define cross_render_sprite_animate       vulkan_render_sprite_animate
+#define cross_render_sprite_preview       vulkan_render_sprite_preview
+#define cross_render_sprite_control       vulkan_render_sprite_control
+#define cross_render_character            vulkan_render_character
+#define cross_render_string_width         vulkan_render_string_width
+#define cross_render_string               vulkan_render_string
+
+#include "xulkan.h"
+
+#endif
diff --git a/xscii.c b/xscii.c
new file mode 100755 (executable)
index 0000000..ad22a13
--- /dev/null
+++ b/xscii.c
@@ -0,0 +1,99 @@
+#include <xolatile/xtandard.h>
+
+static void echo_base (int character, int base, int colour, int effect) {
+       print ("/0 | /-");
+
+       echo_colour (colour, effect);
+
+       if (base == 2) {
+               echo (format_to_string (character, 0, base, 7, '0'));
+       } else if (base == 8) {
+               echo (format_to_string (character, 0, base, 3, '0'));
+       } else if (base == 16) {
+               echo (format_to_string (character, 0, base, 2, '0'));
+       } else {
+               echo (format_to_string (character, 0, base, 3, ' '));
+       }
+
+       echo_cancel ();
+}
+
+static void echo_code (int character) {
+       const char * code [] = {
+               "NUL",  "SOH",  "STX",  "ETX",  "EOT",  "ENQ",  "ACK",  "BEL",  "BS",   "HT",   "LF",   "VT",   "FF",   "CR",   "SO",   "SI",
+               "DLE",  "DC1",  "DC2",  "DC3",  "DC4",  "NAK",  "SYN",  "ETB",  "CAN",  "EM",   "SUB",  "ESC",  "FS",   "GS",   "RS",   "US",
+               "  "
+       };
+
+       if (character == 127) {
+               print ("/0 | /4DEL/-");
+       } else if (character_is_visible (character) == false) {
+               print ("/0 | /4%s/-", code [character]);
+               if (string_length (code [character]) == 2) {
+                       echo (" ");
+               }
+       } else {
+               print ("/0 | /4%c  /-", character);
+       }
+}
+
+static void echo_name (int character) {
+       const char * name [] = {
+               "Null",                         "Start of heading",             "Start of text",                "End of text",
+               "End of transmission",          "Enquiry",                      "Acknowledge",                  "Bell",
+               "Backspace",                    "Horizontal tab",               "Line feed",                    "Vertical tab",
+               "Form feed",                    "Carriage return",              "Shift out",                    "Shift in",
+               "Data link escape",             "Device control 1",             "Device control 2",             "Device control 3",
+               "Device control 4",             "Negative acknowledge",         "Synchronous idle",             "End transmission block",
+               "Cancel",                       "End of medium",                "Substitute",                   "Escape",
+               "File separator",               "Group separator",              "Record separator",             "Unit separator",
+               "Space",                        "Exclamation mark",             "Speech mark",                  "Number sign",
+               "Dollar sign",                  "Percent",                      "Ampersand",                    "Quote",
+               "Open parenthesis",             "Close parenthesis",            "Asterisk",                     "Plus",
+               "Comma",                        "Minus",                        "Period",                       "Slash",
+               "Zero",                         "One",                          "Two",                          "Three",
+               "Four",                         "Five",                         "Six",                          "Seven",
+               "Eight",                        "Nine",                         "Colon",                        "Semicolon",
+               "Open angled bracket",          "Equal",                        "Close angled bracket",         "Question mark",
+               "At sign",                      "Uppercase A",                  "Uppercase B",                  "Uppercase C",
+               "Uppercase D",                  "Uppercase E",                  "Uppercase F",                  "Uppercase G",
+               "Uppercase H",                  "Uppercase I",                  "Uppercase J",                  "Uppercase K",
+               "Uppercase L",                  "Uppercase M",                  "Uppercase N",                  "Uppercase O",
+               "Uppercase P",                  "Uppercase Q",                  "Uppercase R",                  "Uppercase S",
+               "Uppercase T",                  "Uppercase U",                  "Uppercase V",                  "Uppercase W",
+               "Uppercase X",                  "Uppercase Y",                  "Uppercase Z",                  "Opening bracket",
+               "Backslash",                    "Closing bracket",              "Caret",                        "Underscore",
+               "Grave",                        "Lowercase a",                  "Lowercase b",                  "Lowercase c",
+               "Lowercase d",                  "Lowercase e",                  "Lowercase f",                  "Lowercase g",
+               "Lowercase h",                  "Lowercase i",                  "Lowercase j",                  "Lowercase k",
+               "Lowercase l",                  "Lowercase m",                  "Lowercase n",                  "Lowercase o",
+               "Lowercase p",                  "Lowercase q",                  "Lowercase r",                  "Lowercase s",
+               "Lowercase t",                  "Lowercase u",                  "Lowercase v",                  "Lowercase w",
+               "Lowercase x",                  "Lowercase y",                  "Lowercase z",                  "Opening brace",
+               "Vertical bar",                 "Closing brace",                "Tilde",                        "Delete"
+       };
+
+       print ("/0 | /5%s/-", name [character]);
+
+       output ("                                        ", 24 - string_length (name [character]));
+}
+
+int main (void) {
+       int character;
+
+       for (character = 0; character < 128; ++character) {
+               echo_base (character,  2, colour_white, effect_normal);
+               echo_base (character,  8, colour_cyan,  effect_normal);
+               echo_base (character, 10, colour_cyan,  effect_italic);
+               echo_base (character, 16, colour_cyan,  effect_bold);
+
+               echo_code (character);
+               echo_name (character);
+
+               if (character % 2 != 0) {
+                       echo ("\n");
+               }
+       }
+
+       return (log_success);
+}
diff --git a/xtandard.h b/xtandard.h
new file mode 100755 (executable)
index 0000000..b0be1ab
--- /dev/null
@@ -0,0 +1,1136 @@
+///       _                  _               _
+///      | |                | |             | |
+/// __  _| |_ __ _ _ __   __| | __ _ _ __ __| |
+/// \ \/ / __/ _` | '_ \ / _` |/ _` | '__/ _` |
+///  >  <| || (_| | | | | (_| | (_| | | | (_| |
+/// /_/\_\\__\__,_|_| |_|\__,_|\__,_|_|  \__,_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xtandard - Tiny, safe and somewhat sane unity header for what GNU/Linux already provides.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+#define _GNU_SOURCE
+
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <dirent.h>
+
+#define null ((void *) 0)
+
+#define standard_input  (STDIN_FILENO)
+#define standard_output (STDOUT_FILENO)
+#define standard_error  (STDERR_FILENO)
+
+#define file_flag_read     (O_RDONLY)
+#define file_flag_write    (O_WRONLY)
+#define file_flag_edit     (O_RDWR)
+#define file_flag_create   (O_CREAT)
+#define file_flag_append   (O_APPEND)
+#define file_flag_truncate (O_TRUNC)
+
+#define file_seek_current (SEEK_CUR)
+#define file_seek_set     (SEEK_SET)
+#define file_seek_end     (SEEK_END)
+
+#define echo(text) output ((text), sizeof ((text)) - 1)
+
+#define maximum(x, y) (((x) > (y)) ? (x) : (y))
+#define minimum(x, y) (((x) < (y)) ? (x) : (y))
+
+#define array_length(array) (sizeof ((array)) / sizeof (* (array)))
+
+typedef unsigned char  uchar;
+typedef unsigned short ushort;
+typedef unsigned int   uint;
+typedef unsigned long  ulong;
+
+typedef char pstring [256];
+
+typedef enum {
+       false,
+       true
+} bool;
+
+typedef enum {
+       log_success,                    log_warning,                    log_failure,                    log_comment,
+       log_count
+} log_enumeration;
+
+typedef enum {
+       file_type_c_source,             file_type_c_header,             file_type_ada_sexy_body,        file_type_ada_specification,
+       file_type_cpp_source,           file_type_cpp_header,           file_type_fortran_90_source,    file_type_fortran_90_module,
+       file_type_pascal_source,        file_type_d_source,             file_type_go_source,            file_type_jai_source,
+       file_type_assembly,             file_type_eax_assembly,         file_type_gnu_assembly,         file_type_flat_assembly,
+       file_type_haskell_script,       file_type_perl_script,          file_type_cube_script,          file_type_lua_script,
+       file_type_shell_script,         file_type_python_script,        file_type_tcl_script,           file_type_forth_source,
+       file_type_text,                 file_type_markdown,             file_type_html,                 file_type_glsl,
+       file_type_xrocessor,            file_type_xhla,                 file_type_xcript,               file_type_xocument,
+       file_type_xiri,                 file_type_xofya,                file_type_xienna,               file_type_xenka,
+       file_type_xiyagi,               file_type_xoule,                file_type_xikoku,               file_type_xdo,
+       file_type_png_image,            file_type_jxl_image,            file_type_jpg_image,            file_type_tga_image,
+       file_type_wav_sound,            file_type_ogg_sound,            file_type_flac_sound,           file_type_mp3_sound,
+       file_type_obj_model,            file_type_iqm_model,            file_type_md5_model,            file_type_ply_model,
+       file_type_elf_object,           file_type_spir_v_bytecode,
+       file_type_count
+} file_type_enumeration;
+
+typedef enum {
+       effect_normal,                  effect_bold,                    effect_italic,                  effect_undefined_code,
+       effect_underline,               effect_blink,                   effect_reverse,                 effect_invisible_text,
+       effect_count
+} effect_enumeration;
+
+typedef enum {
+       colour_grey,                    colour_red,                     colour_green,                   colour_yellow,
+       colour_blue,                    colour_pink,                    colour_cyan,                    colour_white,
+       colour_count
+} colour_enumeration;
+
+typedef enum {
+       character_null,                 character_start_header,         character_start_text,           character_end_text,
+       character_end_transmission,     character_enquiry,              character_acknowledge,          character_bell,
+       character_backspace,            character_tab_horizontal,       character_line_feed,            character_tab_vertical,
+       character_form_feed,            character_carriage_return,      character_shift_out,            character_shift_in,
+       character_data_link_escape,     character_device_control_1,     character_device_control_2,     character_device_control_3,
+       character_device_control_4,     character_not_acknowledge,      character_synchronous_idle,     character_end_transmission_block,
+       character_cancel,               character_end_medium,           character_substitute,           character_escape,
+       character_file_separator,       character_group_separator,      character_record_separator,     character_unit_separator
+} character_enumeration;
+
+typedef enum {
+       cursor_none,
+       cursor_left,                    cursor_middle,                  cursor_right,
+       cursor_wheel_up,                cursor_wheel_down,
+       cursor_count
+} cursor_enumeration;
+
+typedef enum {
+       signal_none,
+       signal_a,                       signal_b,                       signal_c,                       signal_d,
+       signal_e,                       signal_f,                       signal_g,                       signal_h,
+       signal_i,                       signal_j,                       signal_k,                       signal_l,
+       signal_m,                       signal_n,                       signal_o,                       signal_p,
+       signal_q,                       signal_r,                       signal_s,                       signal_t,
+       signal_u,                       signal_v,                       signal_w,                       signal_x,
+       signal_y,                       signal_z,                       signal_0,                       signal_1,
+       signal_2,                       signal_3,                       signal_4,                       signal_5,
+       signal_6,                       signal_7,                       signal_8,                       signal_9,
+       signal_escape,                  signal_tabulator,               signal_return,                  signal_new_line,
+       signal_slash,                   signal_backslash,               signal_semicolon,               signal_backquote,
+       signal_space,                   signal_backspace,               signal_dot,                     signal_comma,
+       signal_cite,                    signal_caps_lock,               signal_minus,                   signal_equal,
+       signal_left_bracket,            signal_right_bracket,           signal_left_control,            signal_right_control,
+       signal_left_shift,              signal_right_shift,             signal_left_alt,                signal_right_alt,
+       signal_f1,                      signal_f2,                      signal_f3,                      signal_f4,
+       signal_f5,                      signal_f6,                      signal_f7,                      signal_f8,
+       signal_f9,                      signal_f10,                     signal_f11,                     signal_f12,
+       signal_arrow_up,                signal_arrow_down,              signal_arrow_left,              signal_arrow_right,
+       signal_num_lock,                signal_pause_break,             signal_insert,                  signal_home,
+       signal_page_up,                 signal_delete,                  signal_end,                     signal_page_down,
+       signal_key_add,                 signal_key_subtract,            signal_key_multiply,            signal_key_divide,
+       signal_key_enter,               signal_key_dot,                 signal_key_0,                   signal_key_1,
+       signal_key_2,                   signal_key_3,                   signal_key_4,                   signal_key_5,
+       signal_key_6,                   signal_key_7,                   signal_key_8,                   signal_key_9,
+       signal_count
+} signal_enumeration;
+
+static const char * cursor_name [cursor_count] = {
+       "---",
+       "Left button",                  "Middle button",                "Right button",
+       "Scroll up",                    "Scroll down"
+
+};
+
+static const char * signal_name [signal_count] = {
+       "---",
+       "A",                            "B",                            "C",                            "D",
+       "E",                            "F",                            "G",                            "H",
+       "I",                            "J",                            "K",                            "L",
+       "M",                            "N",                            "O",                            "P",
+       "Q",                            "R",                            "S",                            "T",
+       "U",                            "V",                            "W",                            "X",
+       "Y",                            "Z",                            "0",                            "1",
+       "2",                            "3",                            "4",                            "5",
+       "6",                            "7",                            "8",                            "9",
+       "Escape",                       "Tabulator",                    "Return",                       "New line",
+       "Slash",                        "Backslash",                    "Semicolon",                    "Backquote",
+       "Space",                        "Backspace",                    "Dot",                          "Comma",
+       "Cite",                         "Caps lock",                    "Minus",                        "Equal",
+       "Left bracket",                 "Right bracket",                "Left control",                 "Right control",
+       "Left shift",                   "Right shift",                  "Left alt",                     "Right alt",
+       "F1",                           "F2",                           "F3",                           "F4",
+       "F5",                           "F6",                           "F7",                           "F8",
+       "F9",                           "F10",                          "F11",                          "F12",
+       "Arrow up",                     "Arrow down",                   "Arrow left",                   "Arrow right",
+       "Num lock",                     "Pause break",                  "Insert",                       "Home",
+       "Page up",                      "Delete",                       "End",                          "Page down",
+       "Key add",                      "Key subtract",                 "Key multiply",                 "Key divide",
+       "Key enter",                    "Key dot",                      "Key 0",                        "Key 1",
+       "Key 2",                        "Key 3",                        "Key 4",                        "Key 5",
+       "Key 6",                        "Key 7",                        "Key 8",                        "Key 9"
+};
+
+static void randomize_seed_by_time (void) {
+       srand ((uint) time (null));
+}
+
+static int randomize (int from, int to) {
+       return (rand () % (to - from + 1) + from);
+}
+
+static uint urandomize (uint from, uint to) {
+       return ((uint) rand () % (to - from + 1) + from);
+}
+
+static float frandomize (float from, float to) {
+       return (((float) rand () / (float) RAND_MAX) * (to - from) + from);
+}
+
+static int upper_bound (int a, int b) {
+       return ((a > b) ? a : b);
+}
+
+static int lower_bound (int a, int b) {
+       return ((a < b) ? a : b);
+}
+
+static void input (void * data, ulong size) {
+       read (standard_input, data, size);
+}
+
+static void output (const void * data, ulong size) {
+       write (standard_output, data, size);
+}
+
+static void clean_up (void (* procedure) (void)) {
+       atexit (procedure);
+}
+
+#ifdef use_fatal_failure
+static void fatal_failure (bool condition, const char * message) {
+       if (condition == true) {
+               echo ("[\x1b[1;31m FATAL \x1b[0m] ");
+
+               for (int index = 0; message [index] != '\0'; ++index) {
+                       output (& message [index], 1);
+               }
+
+               echo ("\n");
+
+               exit (log_failure);
+       }
+}
+#else
+#define fatal_failure(...)
+#endif
+
+static void execute (const char * command) {
+       int status = 0;
+
+       system (command);
+
+       fatal_failure (status != 0, "execute: System returned an error code.");
+}
+
+static uint tick_tock (void) {
+       return ((uint) clock ());
+}
+
+static ulong nano_time (void) {
+       struct timespec time = { 0 };
+
+       ulong result = 0;
+
+       clock_gettime (CLOCK_MONOTONIC, & time);
+
+       result = 1000000000ul * (ulong) time.tv_sec + (ulong) time.tv_nsec;
+
+       return (result);
+}
+
+static void nano_wait (ulong time) {
+       struct timespec wait = {
+               time / 1000000000,
+               time % 1000000000
+       };
+
+       while (nanosleep (& wait, null)) continue;
+}
+
+static float normal_r (uint colour) { return ((float) ((colour >> 24) & 0xff) / 255.0f); }
+static float normal_g (uint colour) { return ((float) ((colour >> 16) & 0xff) / 255.0f); }
+static float normal_b (uint colour) { return ((float) ((colour >>  8) & 0xff) / 255.0f); }
+static float normal_a (uint colour) { return ((float) ((colour >>  0) & 0xff) / 255.0f); }
+
+static uint channel_r (uint colour) { return ((colour >> 24) & 0xff); }
+static uint channel_g (uint colour) { return ((colour >> 16) & 0xff); }
+static uint channel_b (uint colour) { return ((colour >>  8) & 0xff); }
+static uint channel_a (uint colour) { return ((colour >>  0) & 0xff); }
+
+static uint colour_channel_reverse (uint colour) {
+       uint r = channel_r (colour);
+       uint g = channel_g (colour);
+       uint b = channel_b (colour);
+       uint a = channel_a (colour);
+
+       return ((a << 24) | (b << 16) | (g << 8) | (r << 0));
+}
+
+static uint colour_linear_interpolation (uint colour_a, uint colour_b, float scale) {
+       if (scale <= 0.0f) {
+               return (colour_a);
+       }
+
+       if (scale >= 1.0f) {
+               return (colour_b);
+       }
+
+       uint r = (uint) ((1.0f - scale) * channel_r (colour_a) + scale * channel_r (colour_b));
+       uint g = (uint) ((1.0f - scale) * channel_g (colour_a) + scale * channel_g (colour_b));
+       uint b = (uint) ((1.0f - scale) * channel_b (colour_a) + scale * channel_b (colour_b));
+       uint a = (uint) ((1.0f - scale) * channel_a (colour_a) + scale * channel_a (colour_b));
+
+       return ((r << 24) | (g << 16) | (b << 8) | (a << 0));
+}
+
+static void * allocate (ulong size) {
+       char * data = null;
+
+       fatal_failure (size <= 0, "allocate: Size is equal or below zero.");
+
+       data = calloc (size, sizeof (* data));
+
+       fatal_failure (data == null, "allocate: Function 'calloc' returned null pointer.");
+
+       return (data);
+}
+
+static void * reallocate (void * data, ulong size) {
+       fatal_failure (size <= 0, "reallocate: Size is equal or below zero.");
+
+       data = realloc (data, size);
+
+       fatal_failure (data == null, "reallocate: Function 'realloc' returned null pointer.");
+
+       return (data);
+}
+
+static void * deallocate (void * data) {
+       fatal_failure (data == null, "deallocate: Data is null pointer.");
+
+       free (data);
+
+       return (null);
+}
+
+static void * record (void) {
+       char  * buffer = null;
+       ulong   offset = 0;
+       ulong   memory = 64 * 1024;
+
+       buffer = reallocate (buffer, memory);
+
+       do {
+               if ((offset + 1) % memory == 0) {
+                       buffer = reallocate (buffer, ((offset + 1) / memory + 1) * memory);
+               }
+
+               buffer [offset] = '\0';
+
+               input (& buffer [offset], sizeof (* buffer));
+
+               ++offset;
+       } while (buffer [offset - 1] != '\0');
+
+       buffer [offset - 1] = '\0';
+
+       return (buffer);
+}
+
+static bool character_compare_array (char character, const char * character_array) {
+       for (ulong index = 0; character_array [index] != '\0'; ++index) {
+               if (character == character_array [index]) {
+                       return (true);
+               }
+       }
+
+       return (false);
+}
+
+static bool character_is_uppercase (char character) {
+       return ((character >= 'A') && (character <= 'Z'));
+}
+
+static bool character_is_lowercase (char character) {
+       return ((character >= 'a') && (character <= 'z'));
+}
+
+static bool character_is_digit (char character) {
+       return ((character >= '0') && (character <= '9'));
+}
+
+static bool character_is_letter (char character) {
+       return (((character >= 'A') && (character <= 'Z')) || ((character >= 'a') && (character <= 'z')));
+}
+
+static bool character_is_blank (char character) {
+       return ((character == ' ') || (character == '\t') || (character == '\r') || (character == '\n'));
+}
+
+static bool character_is_symbol (char character) {
+       return (((character >= '!') && (character <= '/')) || ((character >= ':') && (character <= '@'))
+            || ((character >= '[') && (character <= '`')) || ((character >= '{') && (character <= '~')));
+}
+
+static bool character_is_separator (char character) {
+       return ((character != '_') && ((character_is_blank (character) == true) || (character_is_symbol (character) == true)));
+}
+
+static bool character_is_identifier (char character) {
+       return ((character == '_') || (character_is_letter (character) == true) || (character_is_digit (character) == true));
+}
+
+static bool character_is_visible (char character) {
+       return ((character >= '!') && (character <= '~'));
+}
+
+static char * capitalize (char * string) {
+       fatal_failure (string == null, "capitalize: String is null pointer.");
+
+       string [0] -= (character_is_lowercase (string [0]) == true) ? ' ' : '\0';
+
+       return (string);
+}
+
+static char * uppercase (char * string) {
+       fatal_failure (string == null, "uppercase: String is null pointer.");
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               string [index] += (character_is_lowercase (string [index]) == true) ? ' ' : '\0';
+       }
+
+       return (string);
+}
+
+static char * lowercase (char * string) {
+       fatal_failure (string == null, "lowercase: String is null pointer.");
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               string [index] -= (character_is_uppercase (string [index]) == true) ? ' ' : '\0';
+       }
+
+       return (string);
+}
+
+static ulong string_length (const char * string) {
+       ulong length = 0;
+
+       fatal_failure (string == null, "string_length: String is null pointer.");
+
+       for (length = 0; string [length] != '\0'; ++length);
+
+       return (length);
+}
+
+static char * string_nullify (char * string, ulong length) {
+       fatal_failure (string == null, "string_nullify: String is null pointer.");
+       fatal_failure (length <= 0,    "string_nullify: Length is equal or below zero.");
+
+       for (ulong index = 0; index < length; ++index) {
+               string [index] = '\0';
+       }
+
+       return (string);
+}
+
+static char * string_reverse_limit (char * string, ulong limit) {
+       fatal_failure (string == null, "string_reverse_limit: String is null pointer.");
+       fatal_failure (limit  <= 0,    "string_reverse_limit: Limit is equal or below zero.");
+
+       for (ulong index = 0; index < limit / 2; ++index) {
+               char temporary = string [index];
+
+               string [index]             = string [limit - 1 - index];
+               string [limit - 1 - index] = temporary;
+       }
+
+       return (string);
+}
+
+static char * string_reverse (char * string) {
+       return (string_reverse_limit (string, string_length (string)));
+}
+
+static bool string_compare_limit (const char * string_a, const char * string_b, ulong limit) {
+       fatal_failure (string_a == null, "string_compare_limit: First source string is null pointer.");
+       fatal_failure (string_b == null, "string_compare_limit: Second source string is null pointer.");
+       fatal_failure (limit    <= 0,    "string_compare_limit: Limit is equal or below zero.");
+
+       for (ulong index = 0; index < limit; ++index) {
+               if (string_a [index] != string_b [index]) {
+                       return (false);
+               }
+       }
+
+       return (true);
+}
+
+static bool string_compare (const char * string_a, const char * string_b) {
+       return (string_compare_limit (string_a, string_b, string_length (string_a) + 1));
+}
+
+static char * string_copy_limit (char * destination, const char * source, ulong limit) {
+       fatal_failure (destination == null, "string_copy_limit: Destination string is null pointer.");
+       fatal_failure (source      == null, "string_copy_limit: Source string is null pointer.");
+       fatal_failure (limit       <= 0,    "string_copy_limit: Limit is equal or below zero.");
+
+       for (ulong index = 0; index < limit; ++index) {
+               destination [index] = source [index];
+       }
+
+       return (destination);
+}
+
+static char * string_copy (char * destination, const char * source) {
+       return (string_copy_limit (destination, source, string_length (source) + 1));
+}
+
+static char * string_concatenate_limit (char * destination, const char * source, ulong limit) {
+       ulong offset = string_length (destination);
+
+       fatal_failure (destination == null, "string_concatenate_limit: Destination string is null pointer.");
+       fatal_failure (source      == null, "string_concatenate_limit: Source string is null pointer.");
+       fatal_failure (limit       <= 0,    "string_concatenate_limit: Limit is equal or below zero.");
+
+       for (ulong index = 0; index < limit; ++index) {
+               destination [offset + index] = source [index];
+       }
+
+       return (destination);
+}
+
+static char * string_concatenate (char * destination, const char * source) {
+       return (string_concatenate_limit (destination, source, string_length (source) + 1));
+}
+
+static char * string_duplicate (const char * string) {
+       char * duplicate = null;
+
+       duplicate = allocate ((string_length (string) + 1) * sizeof (* duplicate));
+
+       string_copy (duplicate, string);
+
+       return (duplicate);
+}
+
+static char * string_duplicate_limit (const char * string, uint limit) {
+       char * duplicate = null;
+
+       duplicate = allocate ((limit + 1) * sizeof (* duplicate));
+
+       string_copy_limit (duplicate, string, limit);
+
+       return (duplicate);
+}
+
+static char * string_align_left (char * string, ulong amount, char character) {
+       ulong length = string_length (string);
+
+       for (ulong offset = length; offset < amount; ++offset) {
+               string [offset] = character;
+       }
+
+       string [amount] = '\0';
+
+       return (string);
+}
+
+static void memory_nullify (void * memory, ulong size) {
+       char * cast = (char *) memory;
+
+       fatal_failure (memory == null, "memory_nullify: Memory is null pointer.");
+
+       for (ulong offset = 0; offset < size; ++offset) {
+               cast [offset] = (char) 0;
+       }
+}
+
+static int memory_compare (void * memory_0, const void * memory_1, ulong size) {
+             char * cast_0 = (      char *) memory_0;
+       const char * cast_1 = (const char *) memory_1;
+
+       fatal_failure (memory_0 == null, "memory_compare: Memory is null pointer.");
+       fatal_failure (memory_1 == null, "memory_compare: Source is null pointer.");
+
+       for (ulong offset = 0; offset < size; ++offset) {
+               if (cast_0 [offset] != cast_1 [offset]) {
+                       return (false);
+               }
+       }
+
+       return (true);
+}
+
+static void memory_copy (void * destination, const void * source, ulong size) {
+             char * cast_0 = (      char *) destination;
+       const char * cast_1 = (const char *) source;
+
+       fatal_failure (destination == null, "memory_copy: Destination is null pointer.");
+       fatal_failure (source      == null, "memory_copy: Source is null pointer.");
+
+       for (ulong offset = 0; offset < size; ++offset) {
+               cast_0 [offset] = cast_1 [offset];
+       }
+}
+
+static char * string_remove_extension (char * string) {
+       ulong length = string_length (string);
+
+       for (--length; string [length] != '.'; --length);
+
+       string [length] = '\0';
+
+       return (string);
+}
+
+static void echo_clear (void) {
+       echo ("\033[2J\033[H");
+}
+
+static void echo_colour (colour_enumeration colour, effect_enumeration effect) {
+       char format [8] = "\033[ ;3 m";
+
+       format [2] = (char) (effect % effect_count) + '0';
+       format [5] = (char) (colour % colour_count) + '0';
+
+       echo (format);
+}
+
+static void echo_cancel (void) {
+       echo ("\033[0m");
+}
+
+static void show_cursor (bool show) {
+       if (show == true) {
+               echo ("\033[?25h");
+       } else {
+               echo ("\033[?25l");
+       }
+}
+
+static int file_open (const char * path, int mode) {
+       fatal_failure (path == null, "file_open: File path is null pointer.");
+
+       return (open (path, mode, 0777));
+}
+
+static int file_close (int file) {
+       fatal_failure (file == -1, "file_close: Invalid file descriptor.");
+
+       close (file);
+
+       return (-1);
+}
+
+static void file_read (int file, void * data, ulong size) {
+       fatal_failure (file <= -1,   "file_read: File descriptor is closed or invalid.");
+       fatal_failure (data == null, "file_read: Data is null pointer.");
+       fatal_failure (size == 0,    "file_read: Size is zero.");
+
+       read (file, data, size);
+}
+
+static void file_write (int file, const void * data, ulong size) {
+       fatal_failure (file <= -1,   "file_write: File descriptor is closed or invalid.");
+       fatal_failure (data == null, "file_write: Data is null pointer.");
+       fatal_failure (size == 0,    "file_write: Size is zero.");
+
+       write (file, data, size);
+}
+
+static void file_echo (int file, const char * data) {
+       file_write (file, data, string_length (data));
+}
+
+static ulong file_seek (int file, int whence) {
+       fatal_failure (file == -1, "file_seek: Invalid file descriptor.");
+
+       return ((ulong) lseek (file, 0, whence));
+}
+
+static ulong file_size (const char * path) {
+       struct stat data = { 0 };
+
+       fatal_failure (path == null, "file_size: File path is null pointer.");
+
+       lstat (path, & data);
+
+       return ((ulong) data.st_size);
+}
+
+static file_type_enumeration file_type (const char * path) {
+       const char * extensions [file_type_count] = {
+               ".c",           ".h",           ".adb",         ".ads",         ".cpp",         ".hpp",         ".f90",         ".mod",
+               ".pas",         ".d",           ".go",          ".jai",         ".asm",         ".eax",         ".gas",         ".fasm",
+               ".hs",          ".el",          ".cfg",         ".lua",         ".sh",          ".py",          ".tcl",         ".4th",
+               ".txt",         ".md",          ".html",        ".glsl",        ".x",           ".xhla",        ".xs",          ".xd",
+               ".xiri",        ".xofya",       ".xienna",      ".xenka",       ".xiyagi",      ".xoule",       ".xikoku",      ".xdo",
+               ".png",         ".jxl",         ".jpg",         ".tga",         ".wav",         ".ogg",         ".flac",        ".mp3",
+               ".obj",         ".iqm",         ".md5",         ".ply",         ".o",           ".spv"
+       };
+
+       fatal_failure (path == null, "file_type: File path is null pointer.");
+
+       for (; * path != '.'; ++path);
+
+       for (file_type_enumeration type = 0; type != file_type_count; ++type) {
+               if (string_compare (path, extensions [type])) {
+                       return (type);
+               }
+       }
+
+       return (~ 0u);
+}
+
+static bool file_exists (const char * path) {
+       fatal_failure (path == null, "file_record: File path is null pointer.");
+
+       return ((access (path, F_OK) == 0) ? true : false);
+}
+
+static void file_remove (const char * path) {
+       unlink (path);
+}
+
+static void * file_record (const char * path) {
+       int     file = -1;
+       ulong   size = 0;
+       char  * data = null;
+
+       fatal_failure (path == null, "file_record: File path is null pointer.");
+
+       file = file_open (path, file_flag_read);
+       size = file_size (path);
+       data = allocate  (size);
+
+       file_read (file, data, size);
+
+       file = file_close (file);
+
+       return (data);
+}
+
+static char * file_import (const char * path) {
+       int     file = -1;
+       ulong   size = 0;
+       char  * data = null;
+
+       fatal_failure (path == null, "file_import: File path is null pointer.");
+
+       file = file_open (path, file_flag_edit);
+       size = file_size (path) + 1;
+       data = allocate  (size);
+
+       file_read (file, data, size - 1);
+
+       data [size - 1] = '\0';
+
+       file = file_close (file);
+
+       return (data);
+}
+
+static void file_export (const char * path, const char * data) {
+       int file = -1;
+
+       fatal_failure (path == null, "file_export: File path is null pointer.");
+       fatal_failure (data == null, "file_export: Data is null pointer.");
+
+       file = file_open (path, file_flag_write | file_flag_create | file_flag_truncate);
+
+       file_write (file, data, string_length (data));
+
+       file = file_close (file);
+}
+
+static void * folder_open (const char * path) {
+       DIR * folder = null;
+
+       fatal_failure (path == null, "folder_open: Folder path is null pointer.");
+
+       folder = opendir (path);
+
+       return ((void *) folder);
+}
+
+static char * folder_read (void * handle) {
+       struct dirent * file = null;
+
+       DIR * folder = (DIR *) handle;
+
+       fatal_failure (handle == null, "folder_read: Folder handle is null pointer.");
+
+       file = readdir (folder);
+
+       if (file == null) {
+               return (null);
+       } else {
+               return (file->d_name);
+       }
+}
+
+static void * folder_close (void * handle) {
+       DIR * folder = (DIR *) handle;
+
+       fatal_failure (handle == null, "folder_read: Folder handle is null pointer.");
+
+       closedir (folder);
+
+       return (null);
+}
+
+static char * * folder_create_path_list (const char * folder, uint * path_count, bool sort) {
+       void   * handle     = null;
+       char * * path_array = 0;
+
+       (void) sort;
+
+       fatal_failure (folder     == null, "folder_create_path_list: Folder handle is null pointer.");
+       fatal_failure (path_count == null, "folder_create_path_list: Path count address is null pointer.");
+
+       handle = folder_open (folder);
+
+       for (char * path = folder_read (handle); path != null; path = folder_read (handle)) {
+               if (path [0] != '.') {
+                       (* path_count) += 1;
+
+                       path_array = reallocate (path_array, (* path_count) * sizeof (* path_array));
+
+                       path_array [(* path_count) - 1] = allocate ((string_length (path) + 1) * sizeof (* * path_array));
+
+                       string_copy (path_array [(* path_count) - 1], path);
+               }
+       }
+
+       handle = folder_close (handle);
+
+       return (path_array);
+}
+
+static char * * folder_remove_path_list (char * * path_array, uint path_count) {
+       for (uint index = 0; index < path_count; ++index) {
+               path_array [index] = deallocate (path_array [index]);
+       }
+
+       return (deallocate (path_array));
+}
+
+static char * configuration_format (const char * path) {
+       static char buffer [512] = "";
+
+       string_copy (buffer, getenv ("HOME"));
+       string_concatenate (buffer, "/.config/xolatile/");
+       string_concatenate (buffer, path);
+
+       return (buffer);
+}
+
+static bool configuration_exists (const char * path) {
+       return (file_exists (configuration_format (path)));
+}
+
+static void configuration_remove (const char * path) {
+       file_remove (configuration_format (path));
+}
+
+static char * configuration_import (const char * path) {
+       return (file_import (configuration_format (path)));
+}
+
+static void configuration_export (const char * path, const char * data) {
+       file_export (configuration_format (path), data);
+}
+
+static bool argument_compare (const char * argument, const char * short_option, const char * long_option) {
+       return ((string_compare (argument, short_option) == true) || (string_compare (argument, long_option) == true));
+}
+
+static uint string_full_width (const char * string, uint tab_width) {
+       uint width = 0;
+       uint count = 0;
+
+       do {
+               if (* string == '\t') {
+                       count += tab_width;
+               } else if (* string == '\n') {
+                       width = (++count > width) ? count : width;
+                       count = 0;
+               } else {
+                       ++count;
+               }
+       } while (* (++string) != '\0');
+
+       return (width - 1);
+}
+
+static uint string_full_height (const char * string) {
+       uint height = 0;
+
+       do {
+               if (* string == '\n') {
+                       ++height;
+               }
+       } while (* (++string) != '\0');
+
+       return (height + 1);
+}
+
+static uint string_limit_to_number (const char * string, uint limit) {
+       uint number = 0;
+
+       for (uint index = 0; (string [index] != '\0') && (index < limit); ++index) {
+               number *= 10;
+               number += (uint) (string [index] - '0');
+       }
+
+       return (number);
+}
+
+static uint string_to_number (const char * string) {
+       return (string_limit_to_number (string, string_length (string)));
+}
+
+static char * number_to_string (int number) {
+       static char string [34] = "";
+
+       uint index = 0;
+       bool sign  = false;
+
+       string_nullify (string, sizeof (string));
+
+       if (number == 0) {
+               string [0] = '0';
+               string [1] = '\0';
+               return (string);
+       }
+
+       if (number < 0) {
+               number *= -1;
+               sign = true;
+       } else {
+               sign = false;
+       }
+
+       for (index = 0; (number != 0) && (index < (uint) sizeof (string) - 1); ++index) {
+               string [index] = (char) (number % 10) + '0';
+               number /= 10;
+       }
+
+       if (sign == true) {
+               string [index] = '-';
+               ++index;
+       }
+
+       string [index] = '\0';
+
+       string_reverse (string);
+
+       return (string);
+}
+
+static char * format_to_string (int number, bool sign, uint base, ulong amount, char character) {
+       static char string [36];
+
+       int i;
+
+       string_nullify (string, sizeof (string));
+
+       if (number == 0) {
+               string [0] = '0';
+               string [1] = '\0';
+
+               string_align_left (string, amount, character);
+
+               return (string);
+       }
+
+       if (number < 0) {
+               number *= -1;
+       }
+
+       for (i = (string [0] == '-'); number != 0; ++i) {
+               string [i] = "0123456789ABCDEF" [number % base];
+               number /= base;
+       }
+
+       if (sign == true) {
+               string [i] = '-';
+               ++i;
+       }
+
+       string [i] = '\0';
+
+       string_reverse (string);
+
+       string_align_left (string, amount, character);
+
+       return (string);
+}
+
+static char * format (const char * base, ...) {
+       static char string [1024];
+
+       va_list list;
+
+       string_nullify (string, 1024);
+
+       va_start (list, base);
+
+       for (; * base != character_null; ++base) {
+               switch (* base) {
+                       case ('%'): {
+                               ++base;
+                               switch (* base) {
+                                       case ('%'): string_concatenate (string, "%");                                   break;
+                                       case ('i'): string_concatenate (string, number_to_string (va_arg (list, int))); break;
+                                       case ('s'): string_concatenate (string, va_arg (list, char *));                 break;
+                                       default:    string_concatenate (string, "?");                                   break;
+                               }
+                       } break;
+                       default: {
+                               string_concatenate_limit (string, base, 1);
+                       } break;
+               }
+       }
+
+       va_end (list);
+
+       return (string);
+}
+
+static void print (const char * format, ...) {
+       va_list list;
+
+       va_start (list, format);
+
+       for (; * format != character_null; ++format) {
+               switch (* format) {
+                       case ('%'): {
+                               ++format;
+                               switch (* format) {
+                                       case ('%'): {
+                                               output ("%", 1);
+                                       } break;
+                                       case ('i'): {
+                                               char * string = number_to_string (va_arg (list, int));
+                                               output (string, string_length (string));
+                                       } break;
+                                       case ('t'): {
+                                               int toggle = (va_arg (list, int));
+                                               echo_colour ((toggle == true) ? colour_green : colour_red, effect_normal);
+                                               output ((toggle == true) ? "+" : "-", 1);
+                                               echo_cancel ();
+                                       } break;
+                                       case ('b'): {
+                                               int boolean = (va_arg (list, int));
+                                               output ((boolean == true) ? "true" : "false", (boolean == true) ? 4 : 5);
+                                       } break;
+                                       case ('c'): {
+                                               char character = (char) va_arg (list, int);
+                                               output (& character, 1);
+                                       } break;
+                                       case ('s'): {
+                                               char * string = va_arg (list, char *);
+                                               output (string, string_length (string));
+                                       } break;
+                                       default: {
+                                               output ("?", 1);
+                                       } break;
+                               }
+                       } break;
+                       case ('/'): {
+                               ++format;
+                               switch (* format) {
+                                       case ('/'): echo ("/");                          break;
+                                       case ('s'): echo ("[\x1b[1;32mSuccess\x1b[0m]"); break;
+                                       case ('f'): echo ("[\x1b[1;31mFailure\x1b[0m]"); break;
+                                       case ('w'): echo ("[\x1b[1;33mWarning\x1b[0m]"); break;
+                                       case ('c'): echo ("[\x1b[1;30mComment\x1b[0m]"); break;
+                                       case ('A'): echo ("\x1b[0m");                    break;
+                                       case ('B'): echo ("\x1b[1m");                    break;
+                                       case ('C'): echo ("\x1b[2m");                    break;
+                                       case ('D'): echo ("\x1b[3m");                    break;
+                                       case ('E'): echo ("\x1b[4m");                    break;
+                                       case ('F'): echo ("\x1b[5m");                    break;
+                                       case ('G'): echo ("\x1b[6m");                    break;
+                                       case ('H'): echo ("\x1b[7m");                    break;
+                                       case ('0'): echo ("\x1b[30m");                   break;
+                                       case ('1'): echo ("\x1b[31m");                   break;
+                                       case ('2'): echo ("\x1b[32m");                   break;
+                                       case ('3'): echo ("\x1b[33m");                   break;
+                                       case ('4'): echo ("\x1b[34m");                   break;
+                                       case ('5'): echo ("\x1b[35m");                   break;
+                                       case ('6'): echo ("\x1b[36m");                   break;
+                                       case ('7'): echo ("\x1b[37m");                   break;
+                                       case ('-'): echo ("\x1b[0m");                    break;
+                                       default:    echo ("?");                          break;
+                               }
+                       } break;
+                       default: {
+                               output (format, 1);
+                       } break;
+               }
+       }
+
+       va_end (list);
+}
+
+static void uint_exchange (uint * a, uint * b) {
+       uint c = * a;
+
+       * a = * b;
+       * b =   c;
+}
+
+static void float_exchange (float * a, float * b) {
+       float c = * a;
+
+       * a = * b;
+       * b =   c;
+}
+
+#ifdef use_mathematics
+
+#include <math.h>
+
+#define pi (3.14159265f)
+
+static float sign (float x) { return ((x > 0.0f) ? +1.0f : -1.0f); }
+
+static float square_root (float x) { return (sqrtf (x)); }
+static float cube_root   (float x) { return (cbrtf (x)); }
+
+static float sine    (float x) { return (sinf (x)); }
+static float cosine  (float x) { return (cosf (x)); }
+static float tangent (float x) { return (tanf (x)); }
+
+static float arc_sine    (float x) { return (asinf (x)); }
+static float arc_cosine  (float x) { return (acosf (x)); }
+static float arc_tangent (float x) { return (atanf (x)); }
+
+static float cosecant  (float x) { return (1.0f / sinf (x)); }
+static float secant    (float x) { return (1.0f / cosf (x)); }
+static float cotangent (float x) { return (1.0f / tanf (x)); }
+
+#endif
diff --git a/xui.h b/xui.h
new file mode 100755 (executable)
index 0000000..4c4ee36
--- /dev/null
+++ b/xui.h
@@ -0,0 +1,392 @@
+///             _
+/// __  ___   _(_)
+/// \ \/ / | | | |
+///  >  <| |_| | |
+/// /_/\_\\__,_|_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xui - Tiny GUI unity header, I'm not sure if it's immediate or not... Probably not.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+typedef enum {
+       ui_window_left,                 ui_window_right,                ui_window_upper,                ui_window_lower,
+       ui_window_upper_left,           ui_window_upper_right,          ui_window_lower_left,           ui_window_lower_right,
+       ui_frame_left,                  ui_frame_right,                 ui_frame_upper,                 ui_frame_lower,
+       ui_frame_upper_left,            ui_frame_upper_right,           ui_frame_lower_left,            ui_frame_lower_right,
+       ui_status_left,                 ui_status_right,                ui_status_upper,                ui_status_lower,
+       ui_status_upper_left,           ui_status_upper_right,          ui_status_lower_left,           ui_status_lower_right,
+       ui_status_middle,
+       ui_menu_left,                   ui_menu_right,                  ui_menu_upper,                  ui_menu_lower,
+       ui_menu_upper_left,             ui_menu_upper_right,            ui_menu_lower_left,             ui_menu_lower_right,
+       ui_menu_middle,
+       ui_button_left,                 ui_button_right,                ui_button_upper,                ui_button_lower,
+       ui_button_upper_left,           ui_button_upper_right,          ui_button_lower_left,           ui_button_lower_right,
+       ui_button_middle,
+       ui_fill_bar_left,               ui_fill_bar_middle,             ui_fill_bar_right,              ui_fill_bar_base,
+       ui_tiny_fill_bar_middle,        ui_tiny_fill_bar_left,          ui_tiny_fill_bar_right,         ui_tiny_fill_middle,
+       ui_check_box_off,               ui_check_box_on,
+       ui_end_turn_button,
+       ui_icon_frame,                  ui_overicon_frame,              ui_ubericon_frame,
+       ui_scroll_bar_lower,            ui_scroll_bar_middle,           ui_scroll_bar_upper,            ui_scroll_bar_slider,
+       ui_separator_left,              ui_separator_middle,            ui_separator_right,             ui_separator_center,
+       ui_title_bar_left,              ui_title_bar_middle,            ui_title_bar_right,
+       ui_subcount
+} ui_subtype;
+
+typedef enum {
+       ui_window = ui_window_left,
+       ui_frame  = ui_frame_left,
+       ui_status = ui_status_left,
+       ui_menu   = ui_menu_left,
+       ui_button = ui_button_left
+} ui_type;
+
+typedef struct {
+       bool   freeview;
+       uint   ignore;
+       uint   camera_x;
+       uint   camera_y;
+       char * help_box_none;
+       char * help_box_text;
+       uint   help_box_icon;
+       uint   side_panel;
+       uint   font;
+       uint   monofont;
+       uint   sprite [ui_subcount];
+       uint   width  [ui_subcount];
+       uint   height [ui_subcount];
+       uint   separator_size;
+       uint   icon_size;
+       uint   overicon_size;
+       uint   ubericon_size;
+       uint   title_bar_size;
+       uint   fill_bar_size;
+       uint   scroll_bar_size;
+       uint   camera_speed;
+} ui_structure;
+
+static ui_structure * ui_initialize (cross_structure * cross) {
+       const char * subtype_file_name [ui_subcount] = {
+               "window_left",                  "window_right",                 "window_upper",                 "window_lower",
+               "window_upper_left",            "window_upper_right",           "window_lower_left",            "window_lower_right",
+               "frame_left",                   "frame_right",                  "frame_upper",                  "frame_lower",
+               "frame_upper_left",             "frame_upper_right",            "frame_lower_left",             "frame_lower_right",
+               "status_left",                  "status_right",                 "status_upper",                 "status_lower",
+               "status_upper_left",            "status_upper_right",           "status_lower_left",            "status_lower_right",
+               "status_middle",
+               "menu_left",                    "menu_right",                   "menu_upper",                   "menu_lower",
+               "menu_upper_left",              "menu_upper_right",             "menu_lower_left",              "menu_lower_right",
+               "menu_middle",
+               "button_left",                  "button_right",                 "button_upper",                 "button_lower",
+               "button_upper_left",            "button_upper_right",           "button_lower_left",            "button_lower_right",
+               "button_middle",
+               "fill_bar_left",                "fill_bar_middle",              "fill_bar_right",               "fill_bar_base",
+               "tiny_fill_bar_left",           "tiny_fill_bar_middle",         "tiny_fill_bar_right",          "tiny_fill_bar_base",
+               "check_box_off",                "check_box_on",
+               "end_turn_button",
+               "cursor",
+               "icon_frame",                   "overicon_frame",               "ubericon_frame",
+               "scroll_bar_lower",             "scroll_bar_middle",            "scroll_bar_upper",             "scroll_bar_slider",
+               "separator_left",               "separator_middle",             "separator_right",              "separator_center",
+               "title_bar_left",               "title_bar_middle",             "title_bar_right"
+       };
+
+       ui_structure * ui = allocate (sizeof (* ui));
+
+       ui->freeview      = false;
+       ui->ignore        = ~ 0u;
+       ui->camera_x      = 0;
+       ui->camera_y      = 0;
+       ui->help_box_none = string_duplicate ("---");
+       ui->help_box_text = ui->help_box_none;
+       ui->help_box_icon = ui->ignore;
+       ui->side_panel    = 400;
+
+       ui->font     = cross_font_import (cross, configuration_format ("xui/regular"),   ' ', '~', 0xffee0000u);
+       ui->monofont = cross_font_import (cross, configuration_format ("xui/monospace"), ' ', '~', 0xffeeee00u);
+
+       for (uint index = 0; index < ui_subcount; ++index) {
+               const char * file_name = configuration_format (format ("xui/%s", subtype_file_name [index]));
+
+               ui->sprite [index] = cross_sprite_import (cross, file_name);
+
+               ui->width  [index] = cross_sprite_width  (cross, ui->sprite [index]);
+               ui->height [index] = cross_sprite_height (cross, ui->sprite [index]);
+       }
+
+       ui->separator_size  = ui->height [ui_separator_middle];
+       ui->icon_size       = ui->height [ui_icon_frame];
+       ui->overicon_size   = ui->height [ui_overicon_frame];
+       ui->ubericon_size   = ui->height [ui_ubericon_frame];
+       ui->title_bar_size  = ui->height [ui_title_bar_middle];
+       ui->fill_bar_size   = ui->height [ui_fill_bar_middle];
+       ui->scroll_bar_size = ui->width  [ui_scroll_bar_middle];
+
+       print ("[/2Success/-] Initialized UI structure.\n");
+
+       return (ui);
+}
+
+static ui_structure * ui_deinitialize (ui_structure * ui) {
+       ui->help_box_none = deallocate (ui->help_box_none);
+
+       print ("[/2Success/-] Deinitialized UI information.\n");
+
+       return (deallocate (ui));
+}
+
+static int ui_offset_x (const cross_structure * cross, const ui_structure * ui) {
+       return (ui->camera_x - cross->window_width / 2);
+}
+
+static int ui_offset_y (const cross_structure * cross, const ui_structure * ui) {
+       return (ui->camera_y - cross->window_height / 2);
+}
+
+static uint ui_side_panel (const ui_structure * ui) {
+       return (ui->side_panel); /// MAKE IT WINDOW SIZE DEPENDENT?
+}
+
+static void ui_camera_upper (ui_structure * ui) { ui->freeview = true; ui->camera_y -= ui->camera_speed; }
+static void ui_camera_lower (ui_structure * ui) { ui->freeview = true; ui->camera_y += ui->camera_speed; }
+static void ui_camera_left  (ui_structure * ui) { ui->freeview = true; ui->camera_x -= ui->camera_speed; }
+static void ui_camera_right (ui_structure * ui) { ui->freeview = true; ui->camera_x += ui->camera_speed; }
+
+static void ui_render (cross_structure * cross, const ui_structure * ui, ui_subtype index, int x, int y) {
+       cross_render_sprite (cross, ui->sprite [index], x, y);
+}
+
+static void ui_render_colour (cross_structure * cross, const ui_structure * ui, ui_subtype index, uint colour, int x, int y) {
+       cross_render_sprite_colour (cross, ui->sprite [index], colour, x, y);
+}
+
+static void ui_subrender (cross_structure * cross, const ui_structure * ui, ui_subtype index, int x, int y, uint u, uint v, uint width, uint height) {
+       cross_render_sprite_crop (cross, ui->sprite [index], x, y, u, v, width, height);
+}
+
+static void ui_subrender_colour (cross_structure * cross, const ui_structure * ui, ui_subtype index, uint colour, int x, int y, uint u, uint v, uint width, uint height) {
+       cross_render_sprite_crop_colour (cross, ui->sprite [index], colour, x, y, u, v, width, height);
+}
+
+static void ui_render_horizontal (cross_structure * cross, const ui_structure * ui, ui_subtype index, int x, int y, uint width) {
+       const int entire = (width / ui->width [index]) * ui->width [index];
+
+       for (uint margin = 0; margin < width / ui->width [index]; ++margin) {
+               ui_render (cross, ui, index, x + margin * ui->width [index], y);
+       }
+
+       if (width % ui->width [index] > 0) {
+               ui_subrender (cross, ui, index, x + entire, y, 0, 0, width % ui->width [index], ui->height [index]);
+       }
+}
+
+static void ui_render_horizontal_colour (cross_structure * cross, const ui_structure * ui, ui_subtype index, uint colour, int x, int y, uint width) {
+       const int entire = (width / ui->width [index]) * ui->width [index];
+
+       for (uint margin = 0; margin < width / ui->width [index]; ++margin) {
+               ui_render_colour (cross, ui, index, colour, x + margin * ui->width [index], y);
+       }
+
+       if (width % ui->width [index] > 0) {
+               ui_subrender_colour (cross, ui, index, colour, x + entire, y, 0, 0, width % ui->width [index], ui->height [index]);
+       }
+}
+
+static void ui_render_vertical (cross_structure * cross, const ui_structure * ui, ui_subtype index, int x, int y, uint height) {
+       const int entire = (height / ui->height [index]) * ui->height [index];
+
+       for (uint margin = 0; margin < height / ui->height [index]; ++margin) {
+               ui_render (cross, ui, index, x, y + margin * ui->height [index]);
+       }
+
+       if (height % ui->height [index] > 0) {
+               ui_subrender (cross, ui, index, x, y + entire, 0, 0, ui->width [index], height % ui->height [index]);
+       }
+}
+
+static void ui_render_background (cross_structure * cross, const ui_structure * ui, ui_subtype index, int x, int y, uint width, uint height) {
+       const uint offset_x = (width  / ui->width  [index]) * ui->width  [index];
+       const uint offset_y = (height / ui->height [index]) * ui->height [index];
+
+       const uint cutoff_x = width  % ui->width  [index];
+       const uint cutoff_y = height % ui->height [index];
+
+       for (uint vertical = 0; vertical < height / ui->height [index]; ++vertical) {
+               for (uint horizontal = 0; horizontal < width / ui->width [index]; ++horizontal) {
+                       ui_render (cross, ui, index, x + horizontal * ui->width [index], y + vertical * ui->height [index]);
+               }
+
+               if (width % ui->width [index] > 0) {
+                       ui_subrender (cross, ui, index, x + offset_x, y + vertical * ui->height [index], 0, 0, cutoff_x, ui->height [index]);
+               }
+       }
+
+       for (uint horizontal = 0; horizontal < width / ui->width [index]; ++horizontal) {
+               ui_subrender (cross, ui, index, x + horizontal * ui->width [index], y + offset_y, 0, 0, ui->width [index], cutoff_y);
+       }
+
+       if (width % ui->width [index] > 0) {
+               ui_subrender (cross, ui, index, x + offset_x, y + offset_y, 0, 0, cutoff_x, cutoff_y);
+       }
+}
+
+static void ui_screen_overlay (cross_structure * cross) {
+       cross_render_rectangle_vertical_gradient (cross, 0, 0,                        cross->window_width, cross->window_height / 2, 0xcc, 0x00);
+       cross_render_rectangle_vertical_gradient (cross, 0, cross->window_height / 2, cross->window_width, cross->window_height / 2, 0x00, 0xcc);
+}
+
+static void ui_render_grid (cross_structure * cross, const ui_structure * ui, ui_type element, int x, int y, uint width, uint height, uint margin, bool background) {
+       const uint upper_length = width  - ui->width  [element + 4] - ui->width  [element + 5];
+       const uint lower_length = width  - ui->width  [element + 6] - ui->width  [element + 7];
+       const uint left_length  = height - ui->height [element + 4] - ui->height [element + 6];
+       const uint right_length = height - ui->height [element + 5] - ui->height [element + 7];
+
+       const int upper_offset_x =          ui->width  [element + 4];
+       const int lower_offset_x =          ui->width  [element + 6];
+       const int lower_offset_y = height - ui->height [element + 3];
+
+       const int right_offset_x = width - ui->width  [element + 1];
+       const int left_offset_y  =         ui->height [element + 4];
+       const int right_offset_y =         ui->height [element + 5];
+
+       const int upper_right_offset_x = width  - ui->width  [element + 5];
+       const int lower_right_offset_x = width  - ui->width  [element + 7];
+       const int lower_left_offset_y  = height - ui->height [element + 6];
+       const int lower_right_offset_y = height - ui->height [element + 7];
+
+       if ((background == true) && (width > 2 * margin) && (height > 2 * margin)) {
+               ui_render_background (cross, ui, element + 8, x + margin, y + margin, width - 2 * margin, height - 2 * margin);
+       }
+
+       ui_render_vertical (cross, ui, element + 0, x,                  y + left_offset_y,  left_length);
+       ui_render_vertical (cross, ui, element + 1, x + right_offset_x, y + right_offset_y, right_length);
+
+       ui_render_horizontal (cross, ui, element + 2, x + upper_offset_x, y,                  upper_length);
+       ui_render_horizontal (cross, ui, element + 3, x + lower_offset_x, y + lower_offset_y, lower_length);
+
+       ui_render (cross, ui, element + 4, x,                        y);
+       ui_render (cross, ui, element + 5, x + upper_right_offset_x, y);
+       ui_render (cross, ui, element + 6, x,                        y + lower_left_offset_y);
+       ui_render (cross, ui, element + 7, x + lower_right_offset_x, y + lower_right_offset_y);
+}
+
+static void ui_render_window (cross_structure * cross, const ui_structure * ui, int x, int y, uint width, uint height) {
+       ui_render_grid (cross, ui, ui_window, x, y, width, height, 0, false);
+}
+
+static void ui_render_frame (cross_structure * cross, const ui_structure * ui, int x, int y, uint width, uint height) {
+       ui_render_grid (cross, ui, ui_frame, x, y, width, height, 0, false);
+}
+
+static void ui_render_status (cross_structure * cross, const ui_structure * ui, int x, int y, uint width, uint height) {
+       ui_render_grid (cross, ui, ui_status, x, y, width, height, 16, true);
+}
+
+static void ui_render_menu (cross_structure * cross, const ui_structure * ui, int x, int y, uint width, uint height) {
+       ui_render_grid (cross, ui, ui_menu, x, y, width, height, 24, true);
+}
+
+static void ui_render_button (cross_structure * cross, const ui_structure * ui, int x, int y, uint width, uint height) {
+       ui_render_grid (cross, ui, ui_button, x, y, width, height, 16, true);
+}
+
+static void ui_render_separator (cross_structure * cross, const ui_structure * ui, int x, int y, uint width) {
+       const uint margin =                  ui->width [ui_separator_left];
+       const uint length = width - margin - ui->width [ui_separator_right];
+
+       ui_render (cross, ui, ui_separator_left, x, y);
+
+       ui_render_horizontal (cross, ui, ui_separator_middle, x + margin, y, length);
+
+       ui_render (cross, ui, ui_separator_right, x + margin + length, y);
+
+       ui_render (cross, ui, ui_separator_center, x + (width - ui->width [ui_separator_center]) / 2, y);
+}
+
+static void ui_render_title_bar (cross_structure * cross, const ui_structure * ui, const char * title, int x, int y, uint width) {
+       const uint margin =                  ui->width [ui_title_bar_left];
+       const uint length = width - margin - ui->width [ui_title_bar_right];
+
+       ui_render (cross, ui, ui_title_bar_left, x, y);
+
+       ui_render_horizontal (cross, ui, ui_title_bar_middle, x + margin, y, length);
+
+       ui_render (cross, ui, ui_title_bar_right, x + margin + length, y);
+
+       cross_render_string (cross, title, ui->font, x + margin + 8, y + 8, 1, 0x112233ff);
+}
+
+static void ui_render_icon_and_text (cross_structure * cross, const ui_structure * ui, const char * title, uint icon, int x, int y) {
+       cross_render_sprite (cross, icon, x, y);
+
+       cross_render_string (cross, title, ui->font, x - 2 + ui->icon_size, y + 2, 1, 0x112233ffu);
+}
+
+static void ui_render_scroll_bar (cross_structure * cross, const ui_structure * ui, float slider, int x, int y, uint height) {
+       const uint margin =                   ui->height [ui_scroll_bar_upper];
+       const uint length = height - margin - ui->height [ui_scroll_bar_lower];
+
+       ui_render (cross, ui, ui_scroll_bar_upper, x, y);
+
+       ui_render_vertical (cross, ui, ui_scroll_bar_middle, x, y + margin, length);
+
+       ui_render (cross, ui, ui_scroll_bar_lower, x, y + margin + length);
+
+       ui_render (cross, ui, ui_scroll_bar_slider, x, y + margin + (uint) (slider * (float) (length - ui->height [ui_scroll_bar_slider])));
+}
+
+static void ui_render_fill_bar (cross_structure * cross, const ui_structure * ui, float fill, uint colour, int x, int y, uint width) {
+       const uint margin =                  ui->width [ui_fill_bar_left];
+       const uint length = width - margin - ui->width [ui_fill_bar_right];
+
+       ui_render (cross, ui, ui_fill_bar_left, x, y);
+
+       ui_render_horizontal (cross, ui, ui_fill_bar_middle, x + margin, y, length);
+
+       ui_render (cross, ui, ui_fill_bar_right, x + margin + length, y);
+
+       ui_render_horizontal_colour (cross, ui, ui_fill_bar_base, colour, x + margin, y, (uint) (fill * (float) length));
+}
+
+static void ui_render_icon (cross_structure * cross, const ui_structure * ui, uint icon, int x, int y) {
+       cross_render_sprite (cross, ui->sprite [ui_icon_frame], x, y);
+
+       if (icon != ui->ignore) {
+               cross_render_sprite (cross, icon, x, y);
+       }
+}
+
+static void ui_render_overicon (cross_structure * cross, const ui_structure * ui, uint icon, int x, int y) {
+       if (icon != ui->ignore) {
+               cross_render_sprite (cross, icon, x, y);
+       }
+
+       cross_render_sprite (cross, ui->sprite [ui_overicon_frame], x, y);
+}
+
+static void ui_render_ubericon (cross_structure * cross, const ui_structure * ui, uint icon, int x, int y) {
+       cross_render_sprite (cross, ui->sprite [ui_ubericon_frame], x, y);
+
+       if (icon != ui->ignore) {
+               cross_render_sprite (cross, icon, x + 16, y + 16);
+       }
+}
+
+static void ui_render_menu_full (cross_structure * cross, const ui_structure * ui, const char * title, int x, int y, uint width, uint height) {
+       const uint margin = 24;
+
+       ui_screen_overlay (cross);
+
+       ui_render_menu (cross, ui, x, y, width, height);
+
+       if (title != null) {
+               ui_render_title_bar (cross, ui, format ("<%s>", title), x + margin, y + margin / 2 - ui->title_bar_size, width - 2 * margin);
+       }
+}
diff --git a/xui/common/fullscreen_off.png b/xui/common/fullscreen_off.png
new file mode 100755 (executable)
index 0000000..eb8c813
Binary files /dev/null and b/xui/common/fullscreen_off.png differ
diff --git a/xui/common/fullscreen_on.png b/xui/common/fullscreen_on.png
new file mode 100755 (executable)
index 0000000..5d1c0b3
Binary files /dev/null and b/xui/common/fullscreen_on.png differ
diff --git a/xui/common/map_preview_panel_off.png b/xui/common/map_preview_panel_off.png
new file mode 100755 (executable)
index 0000000..d0fb58a
Binary files /dev/null and b/xui/common/map_preview_panel_off.png differ
diff --git a/xui/common/map_preview_panel_on.png b/xui/common/map_preview_panel_on.png
new file mode 100755 (executable)
index 0000000..08dd569
Binary files /dev/null and b/xui/common/map_preview_panel_on.png differ
diff --git a/xui/common/monospace.png b/xui/common/monospace.png
new file mode 100755 (executable)
index 0000000..074f192
Binary files /dev/null and b/xui/common/monospace.png differ
diff --git a/xui/common/palette.png b/xui/common/palette.png
new file mode 100755 (executable)
index 0000000..8a8ab27
Binary files /dev/null and b/xui/common/palette.png differ
diff --git a/xui/common/regular.png b/xui/common/regular.png
new file mode 100755 (executable)
index 0000000..0e5bfe7
Binary files /dev/null and b/xui/common/regular.png differ
diff --git a/xui/common/status_preview_panel_off.png b/xui/common/status_preview_panel_off.png
new file mode 100755 (executable)
index 0000000..fdb5173
Binary files /dev/null and b/xui/common/status_preview_panel_off.png differ
diff --git a/xui/common/status_preview_panel_on.png b/xui/common/status_preview_panel_on.png
new file mode 100755 (executable)
index 0000000..530fc12
Binary files /dev/null and b/xui/common/status_preview_panel_on.png differ
diff --git a/xui/common/text_box_panel_off.png b/xui/common/text_box_panel_off.png
new file mode 100755 (executable)
index 0000000..06efe6c
Binary files /dev/null and b/xui/common/text_box_panel_off.png differ
diff --git a/xui/common/text_box_panel_on.png b/xui/common/text_box_panel_on.png
new file mode 100755 (executable)
index 0000000..0576c96
Binary files /dev/null and b/xui/common/text_box_panel_on.png differ
diff --git a/xui/dwarf/button_left.png b/xui/dwarf/button_left.png
new file mode 100755 (executable)
index 0000000..0631351
Binary files /dev/null and b/xui/dwarf/button_left.png differ
diff --git a/xui/dwarf/button_lower.png b/xui/dwarf/button_lower.png
new file mode 100755 (executable)
index 0000000..01ce842
Binary files /dev/null and b/xui/dwarf/button_lower.png differ
diff --git a/xui/dwarf/button_lower_left.png b/xui/dwarf/button_lower_left.png
new file mode 100755 (executable)
index 0000000..f75c4de
Binary files /dev/null and b/xui/dwarf/button_lower_left.png differ
diff --git a/xui/dwarf/button_lower_right.png b/xui/dwarf/button_lower_right.png
new file mode 100755 (executable)
index 0000000..27ae523
Binary files /dev/null and b/xui/dwarf/button_lower_right.png differ
diff --git a/xui/dwarf/button_middle.png b/xui/dwarf/button_middle.png
new file mode 100755 (executable)
index 0000000..f44ef76
Binary files /dev/null and b/xui/dwarf/button_middle.png differ
diff --git a/xui/dwarf/button_right.png b/xui/dwarf/button_right.png
new file mode 100755 (executable)
index 0000000..6ccd9af
Binary files /dev/null and b/xui/dwarf/button_right.png differ
diff --git a/xui/dwarf/button_upper.png b/xui/dwarf/button_upper.png
new file mode 100755 (executable)
index 0000000..4e57d92
Binary files /dev/null and b/xui/dwarf/button_upper.png differ
diff --git a/xui/dwarf/button_upper_left.png b/xui/dwarf/button_upper_left.png
new file mode 100755 (executable)
index 0000000..e6bde50
Binary files /dev/null and b/xui/dwarf/button_upper_left.png differ
diff --git a/xui/dwarf/button_upper_right.png b/xui/dwarf/button_upper_right.png
new file mode 100755 (executable)
index 0000000..b44cd48
Binary files /dev/null and b/xui/dwarf/button_upper_right.png differ
diff --git a/xui/dwarf/check_box_off.png b/xui/dwarf/check_box_off.png
new file mode 100755 (executable)
index 0000000..5a0b5d1
Binary files /dev/null and b/xui/dwarf/check_box_off.png differ
diff --git a/xui/dwarf/check_box_on.png b/xui/dwarf/check_box_on.png
new file mode 100755 (executable)
index 0000000..8c1d977
Binary files /dev/null and b/xui/dwarf/check_box_on.png differ
diff --git a/xui/dwarf/cursor.png b/xui/dwarf/cursor.png
new file mode 100755 (executable)
index 0000000..918d594
Binary files /dev/null and b/xui/dwarf/cursor.png differ
diff --git a/xui/dwarf/end_turn_button.png b/xui/dwarf/end_turn_button.png
new file mode 100755 (executable)
index 0000000..b89b15c
Binary files /dev/null and b/xui/dwarf/end_turn_button.png differ
diff --git a/xui/dwarf/fill_bar_base.png b/xui/dwarf/fill_bar_base.png
new file mode 100755 (executable)
index 0000000..654b381
Binary files /dev/null and b/xui/dwarf/fill_bar_base.png differ
diff --git a/xui/dwarf/fill_bar_left.png b/xui/dwarf/fill_bar_left.png
new file mode 100755 (executable)
index 0000000..8723288
Binary files /dev/null and b/xui/dwarf/fill_bar_left.png differ
diff --git a/xui/dwarf/fill_bar_middle.png b/xui/dwarf/fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..76ef017
Binary files /dev/null and b/xui/dwarf/fill_bar_middle.png differ
diff --git a/xui/dwarf/fill_bar_right.png b/xui/dwarf/fill_bar_right.png
new file mode 100755 (executable)
index 0000000..8aba62c
Binary files /dev/null and b/xui/dwarf/fill_bar_right.png differ
diff --git a/xui/dwarf/frame_left.png b/xui/dwarf/frame_left.png
new file mode 100755 (executable)
index 0000000..7bbfc97
Binary files /dev/null and b/xui/dwarf/frame_left.png differ
diff --git a/xui/dwarf/frame_lower.png b/xui/dwarf/frame_lower.png
new file mode 100755 (executable)
index 0000000..5816643
Binary files /dev/null and b/xui/dwarf/frame_lower.png differ
diff --git a/xui/dwarf/frame_lower_left.png b/xui/dwarf/frame_lower_left.png
new file mode 100755 (executable)
index 0000000..f8ad153
Binary files /dev/null and b/xui/dwarf/frame_lower_left.png differ
diff --git a/xui/dwarf/frame_lower_right.png b/xui/dwarf/frame_lower_right.png
new file mode 100755 (executable)
index 0000000..7dabfc1
Binary files /dev/null and b/xui/dwarf/frame_lower_right.png differ
diff --git a/xui/dwarf/frame_right.png b/xui/dwarf/frame_right.png
new file mode 100755 (executable)
index 0000000..9085408
Binary files /dev/null and b/xui/dwarf/frame_right.png differ
diff --git a/xui/dwarf/frame_upper.png b/xui/dwarf/frame_upper.png
new file mode 100755 (executable)
index 0000000..e159058
Binary files /dev/null and b/xui/dwarf/frame_upper.png differ
diff --git a/xui/dwarf/frame_upper_left.png b/xui/dwarf/frame_upper_left.png
new file mode 100755 (executable)
index 0000000..ae13b76
Binary files /dev/null and b/xui/dwarf/frame_upper_left.png differ
diff --git a/xui/dwarf/frame_upper_right.png b/xui/dwarf/frame_upper_right.png
new file mode 100755 (executable)
index 0000000..fa0d670
Binary files /dev/null and b/xui/dwarf/frame_upper_right.png differ
diff --git a/xui/dwarf/icon_frame.png b/xui/dwarf/icon_frame.png
new file mode 100755 (executable)
index 0000000..c61f9e3
Binary files /dev/null and b/xui/dwarf/icon_frame.png differ
diff --git a/xui/dwarf/menu_left.png b/xui/dwarf/menu_left.png
new file mode 100755 (executable)
index 0000000..0631351
Binary files /dev/null and b/xui/dwarf/menu_left.png differ
diff --git a/xui/dwarf/menu_lower.png b/xui/dwarf/menu_lower.png
new file mode 100755 (executable)
index 0000000..01ce842
Binary files /dev/null and b/xui/dwarf/menu_lower.png differ
diff --git a/xui/dwarf/menu_lower_left.png b/xui/dwarf/menu_lower_left.png
new file mode 100755 (executable)
index 0000000..f75c4de
Binary files /dev/null and b/xui/dwarf/menu_lower_left.png differ
diff --git a/xui/dwarf/menu_lower_right.png b/xui/dwarf/menu_lower_right.png
new file mode 100755 (executable)
index 0000000..27ae523
Binary files /dev/null and b/xui/dwarf/menu_lower_right.png differ
diff --git a/xui/dwarf/menu_middle.png b/xui/dwarf/menu_middle.png
new file mode 100755 (executable)
index 0000000..f44ef76
Binary files /dev/null and b/xui/dwarf/menu_middle.png differ
diff --git a/xui/dwarf/menu_right.png b/xui/dwarf/menu_right.png
new file mode 100755 (executable)
index 0000000..6ccd9af
Binary files /dev/null and b/xui/dwarf/menu_right.png differ
diff --git a/xui/dwarf/menu_upper.png b/xui/dwarf/menu_upper.png
new file mode 100755 (executable)
index 0000000..4e57d92
Binary files /dev/null and b/xui/dwarf/menu_upper.png differ
diff --git a/xui/dwarf/menu_upper_left.png b/xui/dwarf/menu_upper_left.png
new file mode 100755 (executable)
index 0000000..e6bde50
Binary files /dev/null and b/xui/dwarf/menu_upper_left.png differ
diff --git a/xui/dwarf/menu_upper_right.png b/xui/dwarf/menu_upper_right.png
new file mode 100755 (executable)
index 0000000..b44cd48
Binary files /dev/null and b/xui/dwarf/menu_upper_right.png differ
diff --git a/xui/dwarf/overicon_frame.png b/xui/dwarf/overicon_frame.png
new file mode 100755 (executable)
index 0000000..c54c9be
Binary files /dev/null and b/xui/dwarf/overicon_frame.png differ
diff --git a/xui/dwarf/scroll_bar_lower.png b/xui/dwarf/scroll_bar_lower.png
new file mode 100755 (executable)
index 0000000..16f3ef4
Binary files /dev/null and b/xui/dwarf/scroll_bar_lower.png differ
diff --git a/xui/dwarf/scroll_bar_middle.png b/xui/dwarf/scroll_bar_middle.png
new file mode 100755 (executable)
index 0000000..19063a7
Binary files /dev/null and b/xui/dwarf/scroll_bar_middle.png differ
diff --git a/xui/dwarf/scroll_bar_slider.png b/xui/dwarf/scroll_bar_slider.png
new file mode 100755 (executable)
index 0000000..c54c9be
Binary files /dev/null and b/xui/dwarf/scroll_bar_slider.png differ
diff --git a/xui/dwarf/scroll_bar_upper.png b/xui/dwarf/scroll_bar_upper.png
new file mode 100755 (executable)
index 0000000..bd3b9a7
Binary files /dev/null and b/xui/dwarf/scroll_bar_upper.png differ
diff --git a/xui/dwarf/separator_center.png b/xui/dwarf/separator_center.png
new file mode 100755 (executable)
index 0000000..c54c9be
Binary files /dev/null and b/xui/dwarf/separator_center.png differ
diff --git a/xui/dwarf/separator_left.png b/xui/dwarf/separator_left.png
new file mode 100755 (executable)
index 0000000..23b9cfe
Binary files /dev/null and b/xui/dwarf/separator_left.png differ
diff --git a/xui/dwarf/separator_middle.png b/xui/dwarf/separator_middle.png
new file mode 100755 (executable)
index 0000000..3db79c4
Binary files /dev/null and b/xui/dwarf/separator_middle.png differ
diff --git a/xui/dwarf/separator_right.png b/xui/dwarf/separator_right.png
new file mode 100755 (executable)
index 0000000..7f6f4ce
Binary files /dev/null and b/xui/dwarf/separator_right.png differ
diff --git a/xui/dwarf/status_left.png b/xui/dwarf/status_left.png
new file mode 100755 (executable)
index 0000000..99020ed
Binary files /dev/null and b/xui/dwarf/status_left.png differ
diff --git a/xui/dwarf/status_lower.png b/xui/dwarf/status_lower.png
new file mode 100755 (executable)
index 0000000..1c0a3e7
Binary files /dev/null and b/xui/dwarf/status_lower.png differ
diff --git a/xui/dwarf/status_lower_left.png b/xui/dwarf/status_lower_left.png
new file mode 100755 (executable)
index 0000000..fc161cc
Binary files /dev/null and b/xui/dwarf/status_lower_left.png differ
diff --git a/xui/dwarf/status_lower_right.png b/xui/dwarf/status_lower_right.png
new file mode 100755 (executable)
index 0000000..3366adb
Binary files /dev/null and b/xui/dwarf/status_lower_right.png differ
diff --git a/xui/dwarf/status_middle.png b/xui/dwarf/status_middle.png
new file mode 100755 (executable)
index 0000000..76de51a
Binary files /dev/null and b/xui/dwarf/status_middle.png differ
diff --git a/xui/dwarf/status_right.png b/xui/dwarf/status_right.png
new file mode 100755 (executable)
index 0000000..99020ed
Binary files /dev/null and b/xui/dwarf/status_right.png differ
diff --git a/xui/dwarf/status_upper.png b/xui/dwarf/status_upper.png
new file mode 100755 (executable)
index 0000000..1c0a3e7
Binary files /dev/null and b/xui/dwarf/status_upper.png differ
diff --git a/xui/dwarf/status_upper_left.png b/xui/dwarf/status_upper_left.png
new file mode 100755 (executable)
index 0000000..3d8c271
Binary files /dev/null and b/xui/dwarf/status_upper_left.png differ
diff --git a/xui/dwarf/status_upper_right.png b/xui/dwarf/status_upper_right.png
new file mode 100755 (executable)
index 0000000..00c9afb
Binary files /dev/null and b/xui/dwarf/status_upper_right.png differ
diff --git a/xui/dwarf/tiny_fill_bar_base.png b/xui/dwarf/tiny_fill_bar_base.png
new file mode 100755 (executable)
index 0000000..91f835c
Binary files /dev/null and b/xui/dwarf/tiny_fill_bar_base.png differ
diff --git a/xui/dwarf/tiny_fill_bar_left.png b/xui/dwarf/tiny_fill_bar_left.png
new file mode 100755 (executable)
index 0000000..bf129c0
Binary files /dev/null and b/xui/dwarf/tiny_fill_bar_left.png differ
diff --git a/xui/dwarf/tiny_fill_bar_middle.png b/xui/dwarf/tiny_fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..a872221
Binary files /dev/null and b/xui/dwarf/tiny_fill_bar_middle.png differ
diff --git a/xui/dwarf/tiny_fill_bar_right.png b/xui/dwarf/tiny_fill_bar_right.png
new file mode 100755 (executable)
index 0000000..c35665a
Binary files /dev/null and b/xui/dwarf/tiny_fill_bar_right.png differ
diff --git a/xui/dwarf/title_bar_left.png b/xui/dwarf/title_bar_left.png
new file mode 100755 (executable)
index 0000000..96a3bbb
Binary files /dev/null and b/xui/dwarf/title_bar_left.png differ
diff --git a/xui/dwarf/title_bar_middle.png b/xui/dwarf/title_bar_middle.png
new file mode 100755 (executable)
index 0000000..1286a7f
Binary files /dev/null and b/xui/dwarf/title_bar_middle.png differ
diff --git a/xui/dwarf/title_bar_right.png b/xui/dwarf/title_bar_right.png
new file mode 100755 (executable)
index 0000000..d8dadd2
Binary files /dev/null and b/xui/dwarf/title_bar_right.png differ
diff --git a/xui/dwarf/ubericon_frame.png b/xui/dwarf/ubericon_frame.png
new file mode 100755 (executable)
index 0000000..053c144
Binary files /dev/null and b/xui/dwarf/ubericon_frame.png differ
diff --git a/xui/dwarf/window_left.png b/xui/dwarf/window_left.png
new file mode 100755 (executable)
index 0000000..0c0c404
Binary files /dev/null and b/xui/dwarf/window_left.png differ
diff --git a/xui/dwarf/window_lower.png b/xui/dwarf/window_lower.png
new file mode 100755 (executable)
index 0000000..085ce53
Binary files /dev/null and b/xui/dwarf/window_lower.png differ
diff --git a/xui/dwarf/window_lower_left.png b/xui/dwarf/window_lower_left.png
new file mode 100755 (executable)
index 0000000..eee8dac
Binary files /dev/null and b/xui/dwarf/window_lower_left.png differ
diff --git a/xui/dwarf/window_lower_right.png b/xui/dwarf/window_lower_right.png
new file mode 100755 (executable)
index 0000000..cff21bd
Binary files /dev/null and b/xui/dwarf/window_lower_right.png differ
diff --git a/xui/dwarf/window_right.png b/xui/dwarf/window_right.png
new file mode 100755 (executable)
index 0000000..0c0c404
Binary files /dev/null and b/xui/dwarf/window_right.png differ
diff --git a/xui/dwarf/window_upper.png b/xui/dwarf/window_upper.png
new file mode 100755 (executable)
index 0000000..085ce53
Binary files /dev/null and b/xui/dwarf/window_upper.png differ
diff --git a/xui/dwarf/window_upper_left.png b/xui/dwarf/window_upper_left.png
new file mode 100755 (executable)
index 0000000..ef1e867
Binary files /dev/null and b/xui/dwarf/window_upper_left.png differ
diff --git a/xui/dwarf/window_upper_right.png b/xui/dwarf/window_upper_right.png
new file mode 100755 (executable)
index 0000000..81a118d
Binary files /dev/null and b/xui/dwarf/window_upper_right.png differ
diff --git a/xui/fairy/button_left.png b/xui/fairy/button_left.png
new file mode 100755 (executable)
index 0000000..c4d0d77
Binary files /dev/null and b/xui/fairy/button_left.png differ
diff --git a/xui/fairy/button_lower.png b/xui/fairy/button_lower.png
new file mode 100755 (executable)
index 0000000..f6588bd
Binary files /dev/null and b/xui/fairy/button_lower.png differ
diff --git a/xui/fairy/button_lower_left.png b/xui/fairy/button_lower_left.png
new file mode 100755 (executable)
index 0000000..9cf9145
Binary files /dev/null and b/xui/fairy/button_lower_left.png differ
diff --git a/xui/fairy/button_lower_right.png b/xui/fairy/button_lower_right.png
new file mode 100755 (executable)
index 0000000..f476acb
Binary files /dev/null and b/xui/fairy/button_lower_right.png differ
diff --git a/xui/fairy/button_middle.png b/xui/fairy/button_middle.png
new file mode 100755 (executable)
index 0000000..4106227
Binary files /dev/null and b/xui/fairy/button_middle.png differ
diff --git a/xui/fairy/button_right.png b/xui/fairy/button_right.png
new file mode 100755 (executable)
index 0000000..1a024f4
Binary files /dev/null and b/xui/fairy/button_right.png differ
diff --git a/xui/fairy/button_upper.png b/xui/fairy/button_upper.png
new file mode 100755 (executable)
index 0000000..5ce1f04
Binary files /dev/null and b/xui/fairy/button_upper.png differ
diff --git a/xui/fairy/button_upper_left.png b/xui/fairy/button_upper_left.png
new file mode 100755 (executable)
index 0000000..0f84a4e
Binary files /dev/null and b/xui/fairy/button_upper_left.png differ
diff --git a/xui/fairy/button_upper_right.png b/xui/fairy/button_upper_right.png
new file mode 100755 (executable)
index 0000000..5f38191
Binary files /dev/null and b/xui/fairy/button_upper_right.png differ
diff --git a/xui/fairy/check_box_off.png b/xui/fairy/check_box_off.png
new file mode 100755 (executable)
index 0000000..5e203c6
Binary files /dev/null and b/xui/fairy/check_box_off.png differ
diff --git a/xui/fairy/check_box_on.png b/xui/fairy/check_box_on.png
new file mode 100755 (executable)
index 0000000..85e68e3
Binary files /dev/null and b/xui/fairy/check_box_on.png differ
diff --git a/xui/fairy/cursor.png b/xui/fairy/cursor.png
new file mode 100755 (executable)
index 0000000..56748b5
Binary files /dev/null and b/xui/fairy/cursor.png differ
diff --git a/xui/fairy/end_turn_button.png b/xui/fairy/end_turn_button.png
new file mode 100755 (executable)
index 0000000..4e25d42
Binary files /dev/null and b/xui/fairy/end_turn_button.png differ
diff --git a/xui/fairy/fill_bar_base.png b/xui/fairy/fill_bar_base.png
new file mode 100755 (executable)
index 0000000..cf08f70
Binary files /dev/null and b/xui/fairy/fill_bar_base.png differ
diff --git a/xui/fairy/fill_bar_left.png b/xui/fairy/fill_bar_left.png
new file mode 100755 (executable)
index 0000000..09c10c6
Binary files /dev/null and b/xui/fairy/fill_bar_left.png differ
diff --git a/xui/fairy/fill_bar_middle.png b/xui/fairy/fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..d7b6b15
Binary files /dev/null and b/xui/fairy/fill_bar_middle.png differ
diff --git a/xui/fairy/fill_bar_right.png b/xui/fairy/fill_bar_right.png
new file mode 100755 (executable)
index 0000000..8b0279b
Binary files /dev/null and b/xui/fairy/fill_bar_right.png differ
diff --git a/xui/fairy/frame_left.png b/xui/fairy/frame_left.png
new file mode 100755 (executable)
index 0000000..315183b
Binary files /dev/null and b/xui/fairy/frame_left.png differ
diff --git a/xui/fairy/frame_lower.png b/xui/fairy/frame_lower.png
new file mode 100755 (executable)
index 0000000..c7836fb
Binary files /dev/null and b/xui/fairy/frame_lower.png differ
diff --git a/xui/fairy/frame_lower_left.png b/xui/fairy/frame_lower_left.png
new file mode 100755 (executable)
index 0000000..f3c43c9
Binary files /dev/null and b/xui/fairy/frame_lower_left.png differ
diff --git a/xui/fairy/frame_lower_right.png b/xui/fairy/frame_lower_right.png
new file mode 100755 (executable)
index 0000000..39ab611
Binary files /dev/null and b/xui/fairy/frame_lower_right.png differ
diff --git a/xui/fairy/frame_right.png b/xui/fairy/frame_right.png
new file mode 100755 (executable)
index 0000000..84cc10c
Binary files /dev/null and b/xui/fairy/frame_right.png differ
diff --git a/xui/fairy/frame_upper.png b/xui/fairy/frame_upper.png
new file mode 100755 (executable)
index 0000000..9cde493
Binary files /dev/null and b/xui/fairy/frame_upper.png differ
diff --git a/xui/fairy/frame_upper_left.png b/xui/fairy/frame_upper_left.png
new file mode 100755 (executable)
index 0000000..a060d82
Binary files /dev/null and b/xui/fairy/frame_upper_left.png differ
diff --git a/xui/fairy/frame_upper_right.png b/xui/fairy/frame_upper_right.png
new file mode 100755 (executable)
index 0000000..e0e41ad
Binary files /dev/null and b/xui/fairy/frame_upper_right.png differ
diff --git a/xui/fairy/icon_frame.png b/xui/fairy/icon_frame.png
new file mode 100755 (executable)
index 0000000..9fa4604
Binary files /dev/null and b/xui/fairy/icon_frame.png differ
diff --git a/xui/fairy/menu_left.png b/xui/fairy/menu_left.png
new file mode 100755 (executable)
index 0000000..98adffe
Binary files /dev/null and b/xui/fairy/menu_left.png differ
diff --git a/xui/fairy/menu_lower.png b/xui/fairy/menu_lower.png
new file mode 100755 (executable)
index 0000000..0a93d4b
Binary files /dev/null and b/xui/fairy/menu_lower.png differ
diff --git a/xui/fairy/menu_lower_left.png b/xui/fairy/menu_lower_left.png
new file mode 100755 (executable)
index 0000000..848c900
Binary files /dev/null and b/xui/fairy/menu_lower_left.png differ
diff --git a/xui/fairy/menu_lower_right.png b/xui/fairy/menu_lower_right.png
new file mode 100755 (executable)
index 0000000..4090caf
Binary files /dev/null and b/xui/fairy/menu_lower_right.png differ
diff --git a/xui/fairy/menu_middle.png b/xui/fairy/menu_middle.png
new file mode 100755 (executable)
index 0000000..0019c6e
Binary files /dev/null and b/xui/fairy/menu_middle.png differ
diff --git a/xui/fairy/menu_right.png b/xui/fairy/menu_right.png
new file mode 100755 (executable)
index 0000000..d7f2edb
Binary files /dev/null and b/xui/fairy/menu_right.png differ
diff --git a/xui/fairy/menu_upper.png b/xui/fairy/menu_upper.png
new file mode 100755 (executable)
index 0000000..3cf8921
Binary files /dev/null and b/xui/fairy/menu_upper.png differ
diff --git a/xui/fairy/menu_upper_left.png b/xui/fairy/menu_upper_left.png
new file mode 100755 (executable)
index 0000000..ba4c0a7
Binary files /dev/null and b/xui/fairy/menu_upper_left.png differ
diff --git a/xui/fairy/menu_upper_right.png b/xui/fairy/menu_upper_right.png
new file mode 100755 (executable)
index 0000000..a7f9ce2
Binary files /dev/null and b/xui/fairy/menu_upper_right.png differ
diff --git a/xui/fairy/overicon_frame.png b/xui/fairy/overicon_frame.png
new file mode 100755 (executable)
index 0000000..23cf7c5
Binary files /dev/null and b/xui/fairy/overicon_frame.png differ
diff --git a/xui/fairy/scroll_bar_lower.png b/xui/fairy/scroll_bar_lower.png
new file mode 100755 (executable)
index 0000000..f4c77c1
Binary files /dev/null and b/xui/fairy/scroll_bar_lower.png differ
diff --git a/xui/fairy/scroll_bar_middle.png b/xui/fairy/scroll_bar_middle.png
new file mode 100755 (executable)
index 0000000..d627d82
Binary files /dev/null and b/xui/fairy/scroll_bar_middle.png differ
diff --git a/xui/fairy/scroll_bar_slider.png b/xui/fairy/scroll_bar_slider.png
new file mode 100644 (file)
index 0000000..1ae3016
Binary files /dev/null and b/xui/fairy/scroll_bar_slider.png differ
diff --git a/xui/fairy/scroll_bar_upper.png b/xui/fairy/scroll_bar_upper.png
new file mode 100755 (executable)
index 0000000..fd83ff9
Binary files /dev/null and b/xui/fairy/scroll_bar_upper.png differ
diff --git a/xui/fairy/separator_center.png b/xui/fairy/separator_center.png
new file mode 100644 (file)
index 0000000..1ae3016
Binary files /dev/null and b/xui/fairy/separator_center.png differ
diff --git a/xui/fairy/separator_left.png b/xui/fairy/separator_left.png
new file mode 100755 (executable)
index 0000000..511455c
Binary files /dev/null and b/xui/fairy/separator_left.png differ
diff --git a/xui/fairy/separator_middle.png b/xui/fairy/separator_middle.png
new file mode 100755 (executable)
index 0000000..4435ade
Binary files /dev/null and b/xui/fairy/separator_middle.png differ
diff --git a/xui/fairy/separator_right.png b/xui/fairy/separator_right.png
new file mode 100755 (executable)
index 0000000..1f97a93
Binary files /dev/null and b/xui/fairy/separator_right.png differ
diff --git a/xui/fairy/status_left.png b/xui/fairy/status_left.png
new file mode 100755 (executable)
index 0000000..6bbb1df
Binary files /dev/null and b/xui/fairy/status_left.png differ
diff --git a/xui/fairy/status_lower.png b/xui/fairy/status_lower.png
new file mode 100755 (executable)
index 0000000..ac0f64a
Binary files /dev/null and b/xui/fairy/status_lower.png differ
diff --git a/xui/fairy/status_lower_left.png b/xui/fairy/status_lower_left.png
new file mode 100755 (executable)
index 0000000..5fad49d
Binary files /dev/null and b/xui/fairy/status_lower_left.png differ
diff --git a/xui/fairy/status_lower_right.png b/xui/fairy/status_lower_right.png
new file mode 100755 (executable)
index 0000000..803609e
Binary files /dev/null and b/xui/fairy/status_lower_right.png differ
diff --git a/xui/fairy/status_middle.png b/xui/fairy/status_middle.png
new file mode 100755 (executable)
index 0000000..efaddd0
Binary files /dev/null and b/xui/fairy/status_middle.png differ
diff --git a/xui/fairy/status_right.png b/xui/fairy/status_right.png
new file mode 100755 (executable)
index 0000000..6bbb1df
Binary files /dev/null and b/xui/fairy/status_right.png differ
diff --git a/xui/fairy/status_upper.png b/xui/fairy/status_upper.png
new file mode 100755 (executable)
index 0000000..ac0f64a
Binary files /dev/null and b/xui/fairy/status_upper.png differ
diff --git a/xui/fairy/status_upper_left.png b/xui/fairy/status_upper_left.png
new file mode 100755 (executable)
index 0000000..bc7528d
Binary files /dev/null and b/xui/fairy/status_upper_left.png differ
diff --git a/xui/fairy/status_upper_right.png b/xui/fairy/status_upper_right.png
new file mode 100755 (executable)
index 0000000..24c00a3
Binary files /dev/null and b/xui/fairy/status_upper_right.png differ
diff --git a/xui/fairy/tiny_fill_bar_base.png b/xui/fairy/tiny_fill_bar_base.png
new file mode 100755 (executable)
index 0000000..763dc24
Binary files /dev/null and b/xui/fairy/tiny_fill_bar_base.png differ
diff --git a/xui/fairy/tiny_fill_bar_left.png b/xui/fairy/tiny_fill_bar_left.png
new file mode 100755 (executable)
index 0000000..1c94cf9
Binary files /dev/null and b/xui/fairy/tiny_fill_bar_left.png differ
diff --git a/xui/fairy/tiny_fill_bar_middle.png b/xui/fairy/tiny_fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..b72cabd
Binary files /dev/null and b/xui/fairy/tiny_fill_bar_middle.png differ
diff --git a/xui/fairy/tiny_fill_bar_right.png b/xui/fairy/tiny_fill_bar_right.png
new file mode 100755 (executable)
index 0000000..55bbe08
Binary files /dev/null and b/xui/fairy/tiny_fill_bar_right.png differ
diff --git a/xui/fairy/title_bar_left.png b/xui/fairy/title_bar_left.png
new file mode 100755 (executable)
index 0000000..daa5ec8
Binary files /dev/null and b/xui/fairy/title_bar_left.png differ
diff --git a/xui/fairy/title_bar_middle.png b/xui/fairy/title_bar_middle.png
new file mode 100755 (executable)
index 0000000..be3768c
Binary files /dev/null and b/xui/fairy/title_bar_middle.png differ
diff --git a/xui/fairy/title_bar_right.png b/xui/fairy/title_bar_right.png
new file mode 100755 (executable)
index 0000000..f2fc8b1
Binary files /dev/null and b/xui/fairy/title_bar_right.png differ
diff --git a/xui/fairy/ubericon_frame.png b/xui/fairy/ubericon_frame.png
new file mode 100755 (executable)
index 0000000..9ea054b
Binary files /dev/null and b/xui/fairy/ubericon_frame.png differ
diff --git a/xui/fairy/window_left.png b/xui/fairy/window_left.png
new file mode 100755 (executable)
index 0000000..490e1f1
Binary files /dev/null and b/xui/fairy/window_left.png differ
diff --git a/xui/fairy/window_lower.png b/xui/fairy/window_lower.png
new file mode 100755 (executable)
index 0000000..271096a
Binary files /dev/null and b/xui/fairy/window_lower.png differ
diff --git a/xui/fairy/window_lower_left.png b/xui/fairy/window_lower_left.png
new file mode 100755 (executable)
index 0000000..599be64
Binary files /dev/null and b/xui/fairy/window_lower_left.png differ
diff --git a/xui/fairy/window_lower_right.png b/xui/fairy/window_lower_right.png
new file mode 100755 (executable)
index 0000000..869bbb7
Binary files /dev/null and b/xui/fairy/window_lower_right.png differ
diff --git a/xui/fairy/window_right.png b/xui/fairy/window_right.png
new file mode 100755 (executable)
index 0000000..bf8d98c
Binary files /dev/null and b/xui/fairy/window_right.png differ
diff --git a/xui/fairy/window_upper.png b/xui/fairy/window_upper.png
new file mode 100755 (executable)
index 0000000..271096a
Binary files /dev/null and b/xui/fairy/window_upper.png differ
diff --git a/xui/fairy/window_upper_left.png b/xui/fairy/window_upper_left.png
new file mode 100755 (executable)
index 0000000..b0d76b2
Binary files /dev/null and b/xui/fairy/window_upper_left.png differ
diff --git a/xui/fairy/window_upper_right.png b/xui/fairy/window_upper_right.png
new file mode 100755 (executable)
index 0000000..e6761a4
Binary files /dev/null and b/xui/fairy/window_upper_right.png differ
diff --git a/xui/fullscreen_off.png b/xui/fullscreen_off.png
new file mode 100755 (executable)
index 0000000..eb8c813
Binary files /dev/null and b/xui/fullscreen_off.png differ
diff --git a/xui/fullscreen_on.png b/xui/fullscreen_on.png
new file mode 100755 (executable)
index 0000000..5d1c0b3
Binary files /dev/null and b/xui/fullscreen_on.png differ
diff --git a/xui/gnoll/button_left.png b/xui/gnoll/button_left.png
new file mode 100755 (executable)
index 0000000..9b460c6
Binary files /dev/null and b/xui/gnoll/button_left.png differ
diff --git a/xui/gnoll/button_lower.png b/xui/gnoll/button_lower.png
new file mode 100755 (executable)
index 0000000..ac26ead
Binary files /dev/null and b/xui/gnoll/button_lower.png differ
diff --git a/xui/gnoll/button_lower_left.png b/xui/gnoll/button_lower_left.png
new file mode 100755 (executable)
index 0000000..e4e42f1
Binary files /dev/null and b/xui/gnoll/button_lower_left.png differ
diff --git a/xui/gnoll/button_lower_right.png b/xui/gnoll/button_lower_right.png
new file mode 100755 (executable)
index 0000000..67b0986
Binary files /dev/null and b/xui/gnoll/button_lower_right.png differ
diff --git a/xui/gnoll/button_middle.png b/xui/gnoll/button_middle.png
new file mode 100755 (executable)
index 0000000..58f49ed
Binary files /dev/null and b/xui/gnoll/button_middle.png differ
diff --git a/xui/gnoll/button_right.png b/xui/gnoll/button_right.png
new file mode 100755 (executable)
index 0000000..44aafbc
Binary files /dev/null and b/xui/gnoll/button_right.png differ
diff --git a/xui/gnoll/button_upper.png b/xui/gnoll/button_upper.png
new file mode 100755 (executable)
index 0000000..7a76ea4
Binary files /dev/null and b/xui/gnoll/button_upper.png differ
diff --git a/xui/gnoll/button_upper_left.png b/xui/gnoll/button_upper_left.png
new file mode 100755 (executable)
index 0000000..82f4707
Binary files /dev/null and b/xui/gnoll/button_upper_left.png differ
diff --git a/xui/gnoll/button_upper_right.png b/xui/gnoll/button_upper_right.png
new file mode 100755 (executable)
index 0000000..dffff05
Binary files /dev/null and b/xui/gnoll/button_upper_right.png differ
diff --git a/xui/gnoll/check_box_off.png b/xui/gnoll/check_box_off.png
new file mode 100755 (executable)
index 0000000..db36276
Binary files /dev/null and b/xui/gnoll/check_box_off.png differ
diff --git a/xui/gnoll/check_box_on.png b/xui/gnoll/check_box_on.png
new file mode 100755 (executable)
index 0000000..356dd53
Binary files /dev/null and b/xui/gnoll/check_box_on.png differ
diff --git a/xui/gnoll/cursor.png b/xui/gnoll/cursor.png
new file mode 100755 (executable)
index 0000000..954f141
Binary files /dev/null and b/xui/gnoll/cursor.png differ
diff --git a/xui/gnoll/end_turn_button.png b/xui/gnoll/end_turn_button.png
new file mode 100755 (executable)
index 0000000..34efbcc
Binary files /dev/null and b/xui/gnoll/end_turn_button.png differ
diff --git a/xui/gnoll/fill_bar_base.png b/xui/gnoll/fill_bar_base.png
new file mode 100755 (executable)
index 0000000..5456dc3
Binary files /dev/null and b/xui/gnoll/fill_bar_base.png differ
diff --git a/xui/gnoll/fill_bar_left.png b/xui/gnoll/fill_bar_left.png
new file mode 100755 (executable)
index 0000000..ba693f6
Binary files /dev/null and b/xui/gnoll/fill_bar_left.png differ
diff --git a/xui/gnoll/fill_bar_middle.png b/xui/gnoll/fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..d7cbdf5
Binary files /dev/null and b/xui/gnoll/fill_bar_middle.png differ
diff --git a/xui/gnoll/fill_bar_right.png b/xui/gnoll/fill_bar_right.png
new file mode 100755 (executable)
index 0000000..d5ea533
Binary files /dev/null and b/xui/gnoll/fill_bar_right.png differ
diff --git a/xui/gnoll/frame_left.png b/xui/gnoll/frame_left.png
new file mode 100755 (executable)
index 0000000..007b90c
Binary files /dev/null and b/xui/gnoll/frame_left.png differ
diff --git a/xui/gnoll/frame_lower.png b/xui/gnoll/frame_lower.png
new file mode 100755 (executable)
index 0000000..41c176e
Binary files /dev/null and b/xui/gnoll/frame_lower.png differ
diff --git a/xui/gnoll/frame_lower_left.png b/xui/gnoll/frame_lower_left.png
new file mode 100755 (executable)
index 0000000..35e703c
Binary files /dev/null and b/xui/gnoll/frame_lower_left.png differ
diff --git a/xui/gnoll/frame_lower_right.png b/xui/gnoll/frame_lower_right.png
new file mode 100755 (executable)
index 0000000..ea819a5
Binary files /dev/null and b/xui/gnoll/frame_lower_right.png differ
diff --git a/xui/gnoll/frame_right.png b/xui/gnoll/frame_right.png
new file mode 100755 (executable)
index 0000000..6ed8446
Binary files /dev/null and b/xui/gnoll/frame_right.png differ
diff --git a/xui/gnoll/frame_upper.png b/xui/gnoll/frame_upper.png
new file mode 100755 (executable)
index 0000000..a885c77
Binary files /dev/null and b/xui/gnoll/frame_upper.png differ
diff --git a/xui/gnoll/frame_upper_left.png b/xui/gnoll/frame_upper_left.png
new file mode 100755 (executable)
index 0000000..aee9a04
Binary files /dev/null and b/xui/gnoll/frame_upper_left.png differ
diff --git a/xui/gnoll/frame_upper_right.png b/xui/gnoll/frame_upper_right.png
new file mode 100755 (executable)
index 0000000..2bdcf7c
Binary files /dev/null and b/xui/gnoll/frame_upper_right.png differ
diff --git a/xui/gnoll/icon_frame.png b/xui/gnoll/icon_frame.png
new file mode 100755 (executable)
index 0000000..75b387f
Binary files /dev/null and b/xui/gnoll/icon_frame.png differ
diff --git a/xui/gnoll/menu_left.png b/xui/gnoll/menu_left.png
new file mode 100755 (executable)
index 0000000..a49003c
Binary files /dev/null and b/xui/gnoll/menu_left.png differ
diff --git a/xui/gnoll/menu_lower.png b/xui/gnoll/menu_lower.png
new file mode 100755 (executable)
index 0000000..95cd0df
Binary files /dev/null and b/xui/gnoll/menu_lower.png differ
diff --git a/xui/gnoll/menu_lower_left.png b/xui/gnoll/menu_lower_left.png
new file mode 100755 (executable)
index 0000000..bf7e4fc
Binary files /dev/null and b/xui/gnoll/menu_lower_left.png differ
diff --git a/xui/gnoll/menu_lower_right.png b/xui/gnoll/menu_lower_right.png
new file mode 100755 (executable)
index 0000000..7aa4bb9
Binary files /dev/null and b/xui/gnoll/menu_lower_right.png differ
diff --git a/xui/gnoll/menu_middle.png b/xui/gnoll/menu_middle.png
new file mode 100755 (executable)
index 0000000..a9eddc0
Binary files /dev/null and b/xui/gnoll/menu_middle.png differ
diff --git a/xui/gnoll/menu_right.png b/xui/gnoll/menu_right.png
new file mode 100755 (executable)
index 0000000..88de24a
Binary files /dev/null and b/xui/gnoll/menu_right.png differ
diff --git a/xui/gnoll/menu_upper.png b/xui/gnoll/menu_upper.png
new file mode 100755 (executable)
index 0000000..6b2d146
Binary files /dev/null and b/xui/gnoll/menu_upper.png differ
diff --git a/xui/gnoll/menu_upper_left.png b/xui/gnoll/menu_upper_left.png
new file mode 100755 (executable)
index 0000000..0afa4f7
Binary files /dev/null and b/xui/gnoll/menu_upper_left.png differ
diff --git a/xui/gnoll/menu_upper_right.png b/xui/gnoll/menu_upper_right.png
new file mode 100755 (executable)
index 0000000..9019c35
Binary files /dev/null and b/xui/gnoll/menu_upper_right.png differ
diff --git a/xui/gnoll/overicon_frame.png b/xui/gnoll/overicon_frame.png
new file mode 100755 (executable)
index 0000000..e11efa5
Binary files /dev/null and b/xui/gnoll/overicon_frame.png differ
diff --git a/xui/gnoll/scroll_bar_lower.png b/xui/gnoll/scroll_bar_lower.png
new file mode 100755 (executable)
index 0000000..9a2c0ac
Binary files /dev/null and b/xui/gnoll/scroll_bar_lower.png differ
diff --git a/xui/gnoll/scroll_bar_middle.png b/xui/gnoll/scroll_bar_middle.png
new file mode 100755 (executable)
index 0000000..453539e
Binary files /dev/null and b/xui/gnoll/scroll_bar_middle.png differ
diff --git a/xui/gnoll/scroll_bar_slider.png b/xui/gnoll/scroll_bar_slider.png
new file mode 100755 (executable)
index 0000000..356dd53
Binary files /dev/null and b/xui/gnoll/scroll_bar_slider.png differ
diff --git a/xui/gnoll/scroll_bar_upper.png b/xui/gnoll/scroll_bar_upper.png
new file mode 100755 (executable)
index 0000000..1412b7d
Binary files /dev/null and b/xui/gnoll/scroll_bar_upper.png differ
diff --git a/xui/gnoll/separator_center.png b/xui/gnoll/separator_center.png
new file mode 100755 (executable)
index 0000000..356dd53
Binary files /dev/null and b/xui/gnoll/separator_center.png differ
diff --git a/xui/gnoll/separator_left.png b/xui/gnoll/separator_left.png
new file mode 100755 (executable)
index 0000000..6fdd0eb
Binary files /dev/null and b/xui/gnoll/separator_left.png differ
diff --git a/xui/gnoll/separator_middle.png b/xui/gnoll/separator_middle.png
new file mode 100755 (executable)
index 0000000..5b4a7b4
Binary files /dev/null and b/xui/gnoll/separator_middle.png differ
diff --git a/xui/gnoll/separator_right.png b/xui/gnoll/separator_right.png
new file mode 100755 (executable)
index 0000000..e58569d
Binary files /dev/null and b/xui/gnoll/separator_right.png differ
diff --git a/xui/gnoll/status_left.png b/xui/gnoll/status_left.png
new file mode 100755 (executable)
index 0000000..6eff431
Binary files /dev/null and b/xui/gnoll/status_left.png differ
diff --git a/xui/gnoll/status_lower.png b/xui/gnoll/status_lower.png
new file mode 100755 (executable)
index 0000000..c0c69c9
Binary files /dev/null and b/xui/gnoll/status_lower.png differ
diff --git a/xui/gnoll/status_lower_left.png b/xui/gnoll/status_lower_left.png
new file mode 100755 (executable)
index 0000000..8a73b35
Binary files /dev/null and b/xui/gnoll/status_lower_left.png differ
diff --git a/xui/gnoll/status_lower_right.png b/xui/gnoll/status_lower_right.png
new file mode 100755 (executable)
index 0000000..e655ef5
Binary files /dev/null and b/xui/gnoll/status_lower_right.png differ
diff --git a/xui/gnoll/status_middle.png b/xui/gnoll/status_middle.png
new file mode 100755 (executable)
index 0000000..45b2919
Binary files /dev/null and b/xui/gnoll/status_middle.png differ
diff --git a/xui/gnoll/status_right.png b/xui/gnoll/status_right.png
new file mode 100755 (executable)
index 0000000..b4b4343
Binary files /dev/null and b/xui/gnoll/status_right.png differ
diff --git a/xui/gnoll/status_upper.png b/xui/gnoll/status_upper.png
new file mode 100755 (executable)
index 0000000..acab93f
Binary files /dev/null and b/xui/gnoll/status_upper.png differ
diff --git a/xui/gnoll/status_upper_left.png b/xui/gnoll/status_upper_left.png
new file mode 100755 (executable)
index 0000000..bd0e017
Binary files /dev/null and b/xui/gnoll/status_upper_left.png differ
diff --git a/xui/gnoll/status_upper_right.png b/xui/gnoll/status_upper_right.png
new file mode 100755 (executable)
index 0000000..ecc87d6
Binary files /dev/null and b/xui/gnoll/status_upper_right.png differ
diff --git a/xui/gnoll/tiny_fill_bar_base.png b/xui/gnoll/tiny_fill_bar_base.png
new file mode 100755 (executable)
index 0000000..4d72d7a
Binary files /dev/null and b/xui/gnoll/tiny_fill_bar_base.png differ
diff --git a/xui/gnoll/tiny_fill_bar_left.png b/xui/gnoll/tiny_fill_bar_left.png
new file mode 100755 (executable)
index 0000000..254499a
Binary files /dev/null and b/xui/gnoll/tiny_fill_bar_left.png differ
diff --git a/xui/gnoll/tiny_fill_bar_middle.png b/xui/gnoll/tiny_fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..ee6a587
Binary files /dev/null and b/xui/gnoll/tiny_fill_bar_middle.png differ
diff --git a/xui/gnoll/tiny_fill_bar_right.png b/xui/gnoll/tiny_fill_bar_right.png
new file mode 100755 (executable)
index 0000000..64634e4
Binary files /dev/null and b/xui/gnoll/tiny_fill_bar_right.png differ
diff --git a/xui/gnoll/title_bar_left.png b/xui/gnoll/title_bar_left.png
new file mode 100755 (executable)
index 0000000..a1f300e
Binary files /dev/null and b/xui/gnoll/title_bar_left.png differ
diff --git a/xui/gnoll/title_bar_middle.png b/xui/gnoll/title_bar_middle.png
new file mode 100755 (executable)
index 0000000..b4c3780
Binary files /dev/null and b/xui/gnoll/title_bar_middle.png differ
diff --git a/xui/gnoll/title_bar_right.png b/xui/gnoll/title_bar_right.png
new file mode 100755 (executable)
index 0000000..2b2cec2
Binary files /dev/null and b/xui/gnoll/title_bar_right.png differ
diff --git a/xui/gnoll/ubericon_frame.png b/xui/gnoll/ubericon_frame.png
new file mode 100755 (executable)
index 0000000..342a87a
Binary files /dev/null and b/xui/gnoll/ubericon_frame.png differ
diff --git a/xui/gnoll/window_left.png b/xui/gnoll/window_left.png
new file mode 100755 (executable)
index 0000000..54e60b4
Binary files /dev/null and b/xui/gnoll/window_left.png differ
diff --git a/xui/gnoll/window_lower.png b/xui/gnoll/window_lower.png
new file mode 100755 (executable)
index 0000000..8f62ea9
Binary files /dev/null and b/xui/gnoll/window_lower.png differ
diff --git a/xui/gnoll/window_lower_left.png b/xui/gnoll/window_lower_left.png
new file mode 100755 (executable)
index 0000000..1b68f63
Binary files /dev/null and b/xui/gnoll/window_lower_left.png differ
diff --git a/xui/gnoll/window_lower_right.png b/xui/gnoll/window_lower_right.png
new file mode 100755 (executable)
index 0000000..14e3543
Binary files /dev/null and b/xui/gnoll/window_lower_right.png differ
diff --git a/xui/gnoll/window_right.png b/xui/gnoll/window_right.png
new file mode 100755 (executable)
index 0000000..587bc2a
Binary files /dev/null and b/xui/gnoll/window_right.png differ
diff --git a/xui/gnoll/window_upper.png b/xui/gnoll/window_upper.png
new file mode 100755 (executable)
index 0000000..8f62ea9
Binary files /dev/null and b/xui/gnoll/window_upper.png differ
diff --git a/xui/gnoll/window_upper_left.png b/xui/gnoll/window_upper_left.png
new file mode 100755 (executable)
index 0000000..3e5dc89
Binary files /dev/null and b/xui/gnoll/window_upper_left.png differ
diff --git a/xui/gnoll/window_upper_right.png b/xui/gnoll/window_upper_right.png
new file mode 100755 (executable)
index 0000000..1a24a0a
Binary files /dev/null and b/xui/gnoll/window_upper_right.png differ
diff --git a/xui/goblin/button_left.png b/xui/goblin/button_left.png
new file mode 100755 (executable)
index 0000000..81988fa
Binary files /dev/null and b/xui/goblin/button_left.png differ
diff --git a/xui/goblin/button_lower.png b/xui/goblin/button_lower.png
new file mode 100755 (executable)
index 0000000..c2f6871
Binary files /dev/null and b/xui/goblin/button_lower.png differ
diff --git a/xui/goblin/button_lower_left.png b/xui/goblin/button_lower_left.png
new file mode 100755 (executable)
index 0000000..4159ff6
Binary files /dev/null and b/xui/goblin/button_lower_left.png differ
diff --git a/xui/goblin/button_lower_right.png b/xui/goblin/button_lower_right.png
new file mode 100755 (executable)
index 0000000..5347b56
Binary files /dev/null and b/xui/goblin/button_lower_right.png differ
diff --git a/xui/goblin/button_middle.png b/xui/goblin/button_middle.png
new file mode 100755 (executable)
index 0000000..6e245dc
Binary files /dev/null and b/xui/goblin/button_middle.png differ
diff --git a/xui/goblin/button_right.png b/xui/goblin/button_right.png
new file mode 100755 (executable)
index 0000000..37b71cd
Binary files /dev/null and b/xui/goblin/button_right.png differ
diff --git a/xui/goblin/button_upper.png b/xui/goblin/button_upper.png
new file mode 100755 (executable)
index 0000000..eeb3ad4
Binary files /dev/null and b/xui/goblin/button_upper.png differ
diff --git a/xui/goblin/button_upper_left.png b/xui/goblin/button_upper_left.png
new file mode 100755 (executable)
index 0000000..be65e61
Binary files /dev/null and b/xui/goblin/button_upper_left.png differ
diff --git a/xui/goblin/button_upper_right.png b/xui/goblin/button_upper_right.png
new file mode 100755 (executable)
index 0000000..c75c6b1
Binary files /dev/null and b/xui/goblin/button_upper_right.png differ
diff --git a/xui/goblin/check_box_off.png b/xui/goblin/check_box_off.png
new file mode 100755 (executable)
index 0000000..1ced841
Binary files /dev/null and b/xui/goblin/check_box_off.png differ
diff --git a/xui/goblin/check_box_on.png b/xui/goblin/check_box_on.png
new file mode 100755 (executable)
index 0000000..b6c208a
Binary files /dev/null and b/xui/goblin/check_box_on.png differ
diff --git a/xui/goblin/cursor.png b/xui/goblin/cursor.png
new file mode 100755 (executable)
index 0000000..2efa14f
Binary files /dev/null and b/xui/goblin/cursor.png differ
diff --git a/xui/goblin/end_turn_button.png b/xui/goblin/end_turn_button.png
new file mode 100755 (executable)
index 0000000..3cae1ee
Binary files /dev/null and b/xui/goblin/end_turn_button.png differ
diff --git a/xui/goblin/fill_bar_base.png b/xui/goblin/fill_bar_base.png
new file mode 100755 (executable)
index 0000000..31afc91
Binary files /dev/null and b/xui/goblin/fill_bar_base.png differ
diff --git a/xui/goblin/fill_bar_left.png b/xui/goblin/fill_bar_left.png
new file mode 100755 (executable)
index 0000000..c230edb
Binary files /dev/null and b/xui/goblin/fill_bar_left.png differ
diff --git a/xui/goblin/fill_bar_middle.png b/xui/goblin/fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..4bb058c
Binary files /dev/null and b/xui/goblin/fill_bar_middle.png differ
diff --git a/xui/goblin/fill_bar_right.png b/xui/goblin/fill_bar_right.png
new file mode 100755 (executable)
index 0000000..539e940
Binary files /dev/null and b/xui/goblin/fill_bar_right.png differ
diff --git a/xui/goblin/frame_left.png b/xui/goblin/frame_left.png
new file mode 100755 (executable)
index 0000000..7f7e35d
Binary files /dev/null and b/xui/goblin/frame_left.png differ
diff --git a/xui/goblin/frame_lower.png b/xui/goblin/frame_lower.png
new file mode 100755 (executable)
index 0000000..ed84866
Binary files /dev/null and b/xui/goblin/frame_lower.png differ
diff --git a/xui/goblin/frame_lower_left.png b/xui/goblin/frame_lower_left.png
new file mode 100755 (executable)
index 0000000..41154a0
Binary files /dev/null and b/xui/goblin/frame_lower_left.png differ
diff --git a/xui/goblin/frame_lower_right.png b/xui/goblin/frame_lower_right.png
new file mode 100755 (executable)
index 0000000..d6366c7
Binary files /dev/null and b/xui/goblin/frame_lower_right.png differ
diff --git a/xui/goblin/frame_right.png b/xui/goblin/frame_right.png
new file mode 100755 (executable)
index 0000000..41d3913
Binary files /dev/null and b/xui/goblin/frame_right.png differ
diff --git a/xui/goblin/frame_upper.png b/xui/goblin/frame_upper.png
new file mode 100755 (executable)
index 0000000..180bf96
Binary files /dev/null and b/xui/goblin/frame_upper.png differ
diff --git a/xui/goblin/frame_upper_left.png b/xui/goblin/frame_upper_left.png
new file mode 100755 (executable)
index 0000000..07e780d
Binary files /dev/null and b/xui/goblin/frame_upper_left.png differ
diff --git a/xui/goblin/frame_upper_right.png b/xui/goblin/frame_upper_right.png
new file mode 100755 (executable)
index 0000000..ed88553
Binary files /dev/null and b/xui/goblin/frame_upper_right.png differ
diff --git a/xui/goblin/icon_frame.png b/xui/goblin/icon_frame.png
new file mode 100755 (executable)
index 0000000..cce0dcd
Binary files /dev/null and b/xui/goblin/icon_frame.png differ
diff --git a/xui/goblin/menu_left.png b/xui/goblin/menu_left.png
new file mode 100755 (executable)
index 0000000..c976421
Binary files /dev/null and b/xui/goblin/menu_left.png differ
diff --git a/xui/goblin/menu_lower.png b/xui/goblin/menu_lower.png
new file mode 100755 (executable)
index 0000000..6bbb18f
Binary files /dev/null and b/xui/goblin/menu_lower.png differ
diff --git a/xui/goblin/menu_lower_left.png b/xui/goblin/menu_lower_left.png
new file mode 100755 (executable)
index 0000000..97965e4
Binary files /dev/null and b/xui/goblin/menu_lower_left.png differ
diff --git a/xui/goblin/menu_lower_right.png b/xui/goblin/menu_lower_right.png
new file mode 100755 (executable)
index 0000000..70cdc5e
Binary files /dev/null and b/xui/goblin/menu_lower_right.png differ
diff --git a/xui/goblin/menu_middle.png b/xui/goblin/menu_middle.png
new file mode 100755 (executable)
index 0000000..6e245dc
Binary files /dev/null and b/xui/goblin/menu_middle.png differ
diff --git a/xui/goblin/menu_right.png b/xui/goblin/menu_right.png
new file mode 100755 (executable)
index 0000000..96f24b4
Binary files /dev/null and b/xui/goblin/menu_right.png differ
diff --git a/xui/goblin/menu_upper.png b/xui/goblin/menu_upper.png
new file mode 100755 (executable)
index 0000000..075d136
Binary files /dev/null and b/xui/goblin/menu_upper.png differ
diff --git a/xui/goblin/menu_upper_left.png b/xui/goblin/menu_upper_left.png
new file mode 100755 (executable)
index 0000000..2244e57
Binary files /dev/null and b/xui/goblin/menu_upper_left.png differ
diff --git a/xui/goblin/menu_upper_right.png b/xui/goblin/menu_upper_right.png
new file mode 100755 (executable)
index 0000000..17a673d
Binary files /dev/null and b/xui/goblin/menu_upper_right.png differ
diff --git a/xui/goblin/overicon_frame.png b/xui/goblin/overicon_frame.png
new file mode 100755 (executable)
index 0000000..f090678
Binary files /dev/null and b/xui/goblin/overicon_frame.png differ
diff --git a/xui/goblin/scroll_bar_lower.png b/xui/goblin/scroll_bar_lower.png
new file mode 100755 (executable)
index 0000000..0ea255d
Binary files /dev/null and b/xui/goblin/scroll_bar_lower.png differ
diff --git a/xui/goblin/scroll_bar_middle.png b/xui/goblin/scroll_bar_middle.png
new file mode 100755 (executable)
index 0000000..c13f056
Binary files /dev/null and b/xui/goblin/scroll_bar_middle.png differ
diff --git a/xui/goblin/scroll_bar_slider.png b/xui/goblin/scroll_bar_slider.png
new file mode 100755 (executable)
index 0000000..b6c208a
Binary files /dev/null and b/xui/goblin/scroll_bar_slider.png differ
diff --git a/xui/goblin/scroll_bar_upper.png b/xui/goblin/scroll_bar_upper.png
new file mode 100755 (executable)
index 0000000..5b90ade
Binary files /dev/null and b/xui/goblin/scroll_bar_upper.png differ
diff --git a/xui/goblin/separator_center.png b/xui/goblin/separator_center.png
new file mode 100755 (executable)
index 0000000..b6c208a
Binary files /dev/null and b/xui/goblin/separator_center.png differ
diff --git a/xui/goblin/separator_left.png b/xui/goblin/separator_left.png
new file mode 100755 (executable)
index 0000000..7c9c6cf
Binary files /dev/null and b/xui/goblin/separator_left.png differ
diff --git a/xui/goblin/separator_middle.png b/xui/goblin/separator_middle.png
new file mode 100755 (executable)
index 0000000..6403039
Binary files /dev/null and b/xui/goblin/separator_middle.png differ
diff --git a/xui/goblin/separator_right.png b/xui/goblin/separator_right.png
new file mode 100755 (executable)
index 0000000..45f639f
Binary files /dev/null and b/xui/goblin/separator_right.png differ
diff --git a/xui/goblin/status_left.png b/xui/goblin/status_left.png
new file mode 100755 (executable)
index 0000000..8b45355
Binary files /dev/null and b/xui/goblin/status_left.png differ
diff --git a/xui/goblin/status_lower.png b/xui/goblin/status_lower.png
new file mode 100755 (executable)
index 0000000..79d5a8e
Binary files /dev/null and b/xui/goblin/status_lower.png differ
diff --git a/xui/goblin/status_lower_left.png b/xui/goblin/status_lower_left.png
new file mode 100755 (executable)
index 0000000..28778cb
Binary files /dev/null and b/xui/goblin/status_lower_left.png differ
diff --git a/xui/goblin/status_lower_right.png b/xui/goblin/status_lower_right.png
new file mode 100755 (executable)
index 0000000..63d7da9
Binary files /dev/null and b/xui/goblin/status_lower_right.png differ
diff --git a/xui/goblin/status_middle.png b/xui/goblin/status_middle.png
new file mode 100755 (executable)
index 0000000..a412403
Binary files /dev/null and b/xui/goblin/status_middle.png differ
diff --git a/xui/goblin/status_right.png b/xui/goblin/status_right.png
new file mode 100755 (executable)
index 0000000..6456926
Binary files /dev/null and b/xui/goblin/status_right.png differ
diff --git a/xui/goblin/status_upper.png b/xui/goblin/status_upper.png
new file mode 100755 (executable)
index 0000000..653ca08
Binary files /dev/null and b/xui/goblin/status_upper.png differ
diff --git a/xui/goblin/status_upper_left.png b/xui/goblin/status_upper_left.png
new file mode 100755 (executable)
index 0000000..93008da
Binary files /dev/null and b/xui/goblin/status_upper_left.png differ
diff --git a/xui/goblin/status_upper_right.png b/xui/goblin/status_upper_right.png
new file mode 100755 (executable)
index 0000000..ee50986
Binary files /dev/null and b/xui/goblin/status_upper_right.png differ
diff --git a/xui/goblin/tiny_fill_bar_base.png b/xui/goblin/tiny_fill_bar_base.png
new file mode 100755 (executable)
index 0000000..8761bff
Binary files /dev/null and b/xui/goblin/tiny_fill_bar_base.png differ
diff --git a/xui/goblin/tiny_fill_bar_left.png b/xui/goblin/tiny_fill_bar_left.png
new file mode 100755 (executable)
index 0000000..4266bbb
Binary files /dev/null and b/xui/goblin/tiny_fill_bar_left.png differ
diff --git a/xui/goblin/tiny_fill_bar_middle.png b/xui/goblin/tiny_fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..c906642
Binary files /dev/null and b/xui/goblin/tiny_fill_bar_middle.png differ
diff --git a/xui/goblin/tiny_fill_bar_right.png b/xui/goblin/tiny_fill_bar_right.png
new file mode 100755 (executable)
index 0000000..b21e6bc
Binary files /dev/null and b/xui/goblin/tiny_fill_bar_right.png differ
diff --git a/xui/goblin/title_bar_left.png b/xui/goblin/title_bar_left.png
new file mode 100755 (executable)
index 0000000..a8eb724
Binary files /dev/null and b/xui/goblin/title_bar_left.png differ
diff --git a/xui/goblin/title_bar_middle.png b/xui/goblin/title_bar_middle.png
new file mode 100755 (executable)
index 0000000..31f331e
Binary files /dev/null and b/xui/goblin/title_bar_middle.png differ
diff --git a/xui/goblin/title_bar_right.png b/xui/goblin/title_bar_right.png
new file mode 100755 (executable)
index 0000000..611c364
Binary files /dev/null and b/xui/goblin/title_bar_right.png differ
diff --git a/xui/goblin/ubericon_frame.png b/xui/goblin/ubericon_frame.png
new file mode 100755 (executable)
index 0000000..a1b8b20
Binary files /dev/null and b/xui/goblin/ubericon_frame.png differ
diff --git a/xui/goblin/window_left.png b/xui/goblin/window_left.png
new file mode 100755 (executable)
index 0000000..3d8907e
Binary files /dev/null and b/xui/goblin/window_left.png differ
diff --git a/xui/goblin/window_lower.png b/xui/goblin/window_lower.png
new file mode 100755 (executable)
index 0000000..20bb0c0
Binary files /dev/null and b/xui/goblin/window_lower.png differ
diff --git a/xui/goblin/window_lower_left.png b/xui/goblin/window_lower_left.png
new file mode 100755 (executable)
index 0000000..71bfaa3
Binary files /dev/null and b/xui/goblin/window_lower_left.png differ
diff --git a/xui/goblin/window_lower_right.png b/xui/goblin/window_lower_right.png
new file mode 100755 (executable)
index 0000000..8c8d536
Binary files /dev/null and b/xui/goblin/window_lower_right.png differ
diff --git a/xui/goblin/window_right.png b/xui/goblin/window_right.png
new file mode 100755 (executable)
index 0000000..590f944
Binary files /dev/null and b/xui/goblin/window_right.png differ
diff --git a/xui/goblin/window_upper.png b/xui/goblin/window_upper.png
new file mode 100755 (executable)
index 0000000..7033c45
Binary files /dev/null and b/xui/goblin/window_upper.png differ
diff --git a/xui/goblin/window_upper_left.png b/xui/goblin/window_upper_left.png
new file mode 100755 (executable)
index 0000000..52275da
Binary files /dev/null and b/xui/goblin/window_upper_left.png differ
diff --git a/xui/goblin/window_upper_right.png b/xui/goblin/window_upper_right.png
new file mode 100755 (executable)
index 0000000..8ebab21
Binary files /dev/null and b/xui/goblin/window_upper_right.png differ
diff --git a/xui/imp/button_left.png b/xui/imp/button_left.png
new file mode 100755 (executable)
index 0000000..6901c55
Binary files /dev/null and b/xui/imp/button_left.png differ
diff --git a/xui/imp/button_lower.png b/xui/imp/button_lower.png
new file mode 100755 (executable)
index 0000000..f08242f
Binary files /dev/null and b/xui/imp/button_lower.png differ
diff --git a/xui/imp/button_lower_left.png b/xui/imp/button_lower_left.png
new file mode 100755 (executable)
index 0000000..7e32a23
Binary files /dev/null and b/xui/imp/button_lower_left.png differ
diff --git a/xui/imp/button_lower_right.png b/xui/imp/button_lower_right.png
new file mode 100755 (executable)
index 0000000..24b711e
Binary files /dev/null and b/xui/imp/button_lower_right.png differ
diff --git a/xui/imp/button_middle.png b/xui/imp/button_middle.png
new file mode 100755 (executable)
index 0000000..251460f
Binary files /dev/null and b/xui/imp/button_middle.png differ
diff --git a/xui/imp/button_right.png b/xui/imp/button_right.png
new file mode 100755 (executable)
index 0000000..a61e82a
Binary files /dev/null and b/xui/imp/button_right.png differ
diff --git a/xui/imp/button_upper.png b/xui/imp/button_upper.png
new file mode 100755 (executable)
index 0000000..004d906
Binary files /dev/null and b/xui/imp/button_upper.png differ
diff --git a/xui/imp/button_upper_left.png b/xui/imp/button_upper_left.png
new file mode 100755 (executable)
index 0000000..7e32a23
Binary files /dev/null and b/xui/imp/button_upper_left.png differ
diff --git a/xui/imp/button_upper_right.png b/xui/imp/button_upper_right.png
new file mode 100755 (executable)
index 0000000..7e32a23
Binary files /dev/null and b/xui/imp/button_upper_right.png differ
diff --git a/xui/imp/check_box_off.png b/xui/imp/check_box_off.png
new file mode 100755 (executable)
index 0000000..2fd2752
Binary files /dev/null and b/xui/imp/check_box_off.png differ
diff --git a/xui/imp/check_box_on.png b/xui/imp/check_box_on.png
new file mode 100755 (executable)
index 0000000..4414b36
Binary files /dev/null and b/xui/imp/check_box_on.png differ
diff --git a/xui/imp/cursor.png b/xui/imp/cursor.png
new file mode 100755 (executable)
index 0000000..31c5316
Binary files /dev/null and b/xui/imp/cursor.png differ
diff --git a/xui/imp/end_turn_button.png b/xui/imp/end_turn_button.png
new file mode 100755 (executable)
index 0000000..57cdd80
Binary files /dev/null and b/xui/imp/end_turn_button.png differ
diff --git a/xui/imp/fill_bar_base.png b/xui/imp/fill_bar_base.png
new file mode 100755 (executable)
index 0000000..11b3869
Binary files /dev/null and b/xui/imp/fill_bar_base.png differ
diff --git a/xui/imp/fill_bar_left.png b/xui/imp/fill_bar_left.png
new file mode 100755 (executable)
index 0000000..47e2044
Binary files /dev/null and b/xui/imp/fill_bar_left.png differ
diff --git a/xui/imp/fill_bar_middle.png b/xui/imp/fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..b133332
Binary files /dev/null and b/xui/imp/fill_bar_middle.png differ
diff --git a/xui/imp/fill_bar_right.png b/xui/imp/fill_bar_right.png
new file mode 100755 (executable)
index 0000000..524795f
Binary files /dev/null and b/xui/imp/fill_bar_right.png differ
diff --git a/xui/imp/frame_left.png b/xui/imp/frame_left.png
new file mode 100755 (executable)
index 0000000..246ee15
Binary files /dev/null and b/xui/imp/frame_left.png differ
diff --git a/xui/imp/frame_lower.png b/xui/imp/frame_lower.png
new file mode 100755 (executable)
index 0000000..564f7ec
Binary files /dev/null and b/xui/imp/frame_lower.png differ
diff --git a/xui/imp/frame_lower_left.png b/xui/imp/frame_lower_left.png
new file mode 100755 (executable)
index 0000000..6b5338f
Binary files /dev/null and b/xui/imp/frame_lower_left.png differ
diff --git a/xui/imp/frame_lower_right.png b/xui/imp/frame_lower_right.png
new file mode 100755 (executable)
index 0000000..d324d70
Binary files /dev/null and b/xui/imp/frame_lower_right.png differ
diff --git a/xui/imp/frame_right.png b/xui/imp/frame_right.png
new file mode 100755 (executable)
index 0000000..bb7fc67
Binary files /dev/null and b/xui/imp/frame_right.png differ
diff --git a/xui/imp/frame_upper.png b/xui/imp/frame_upper.png
new file mode 100755 (executable)
index 0000000..1bb3b0d
Binary files /dev/null and b/xui/imp/frame_upper.png differ
diff --git a/xui/imp/frame_upper_left.png b/xui/imp/frame_upper_left.png
new file mode 100755 (executable)
index 0000000..82bcc93
Binary files /dev/null and b/xui/imp/frame_upper_left.png differ
diff --git a/xui/imp/frame_upper_right.png b/xui/imp/frame_upper_right.png
new file mode 100755 (executable)
index 0000000..a415bb1
Binary files /dev/null and b/xui/imp/frame_upper_right.png differ
diff --git a/xui/imp/icon_frame.png b/xui/imp/icon_frame.png
new file mode 100755 (executable)
index 0000000..edc3346
Binary files /dev/null and b/xui/imp/icon_frame.png differ
diff --git a/xui/imp/menu_left.png b/xui/imp/menu_left.png
new file mode 100755 (executable)
index 0000000..d391c22
Binary files /dev/null and b/xui/imp/menu_left.png differ
diff --git a/xui/imp/menu_lower.png b/xui/imp/menu_lower.png
new file mode 100755 (executable)
index 0000000..b278aef
Binary files /dev/null and b/xui/imp/menu_lower.png differ
diff --git a/xui/imp/menu_lower_left.png b/xui/imp/menu_lower_left.png
new file mode 100755 (executable)
index 0000000..7e32a23
Binary files /dev/null and b/xui/imp/menu_lower_left.png differ
diff --git a/xui/imp/menu_lower_right.png b/xui/imp/menu_lower_right.png
new file mode 100755 (executable)
index 0000000..24b711e
Binary files /dev/null and b/xui/imp/menu_lower_right.png differ
diff --git a/xui/imp/menu_middle.png b/xui/imp/menu_middle.png
new file mode 100755 (executable)
index 0000000..251460f
Binary files /dev/null and b/xui/imp/menu_middle.png differ
diff --git a/xui/imp/menu_right.png b/xui/imp/menu_right.png
new file mode 100755 (executable)
index 0000000..ea0408b
Binary files /dev/null and b/xui/imp/menu_right.png differ
diff --git a/xui/imp/menu_upper.png b/xui/imp/menu_upper.png
new file mode 100755 (executable)
index 0000000..6bad659
Binary files /dev/null and b/xui/imp/menu_upper.png differ
diff --git a/xui/imp/menu_upper_left.png b/xui/imp/menu_upper_left.png
new file mode 100755 (executable)
index 0000000..7e32a23
Binary files /dev/null and b/xui/imp/menu_upper_left.png differ
diff --git a/xui/imp/menu_upper_right.png b/xui/imp/menu_upper_right.png
new file mode 100755 (executable)
index 0000000..7e32a23
Binary files /dev/null and b/xui/imp/menu_upper_right.png differ
diff --git a/xui/imp/overicon_frame.png b/xui/imp/overicon_frame.png
new file mode 100755 (executable)
index 0000000..5636691
Binary files /dev/null and b/xui/imp/overicon_frame.png differ
diff --git a/xui/imp/scroll_bar_lower.png b/xui/imp/scroll_bar_lower.png
new file mode 100755 (executable)
index 0000000..5e2e671
Binary files /dev/null and b/xui/imp/scroll_bar_lower.png differ
diff --git a/xui/imp/scroll_bar_middle.png b/xui/imp/scroll_bar_middle.png
new file mode 100755 (executable)
index 0000000..a0cf11c
Binary files /dev/null and b/xui/imp/scroll_bar_middle.png differ
diff --git a/xui/imp/scroll_bar_slider.png b/xui/imp/scroll_bar_slider.png
new file mode 100644 (file)
index 0000000..216040c
Binary files /dev/null and b/xui/imp/scroll_bar_slider.png differ
diff --git a/xui/imp/scroll_bar_upper.png b/xui/imp/scroll_bar_upper.png
new file mode 100755 (executable)
index 0000000..c17f9b4
Binary files /dev/null and b/xui/imp/scroll_bar_upper.png differ
diff --git a/xui/imp/separator_center.png b/xui/imp/separator_center.png
new file mode 100644 (file)
index 0000000..216040c
Binary files /dev/null and b/xui/imp/separator_center.png differ
diff --git a/xui/imp/separator_left.png b/xui/imp/separator_left.png
new file mode 100755 (executable)
index 0000000..96b219e
Binary files /dev/null and b/xui/imp/separator_left.png differ
diff --git a/xui/imp/separator_middle.png b/xui/imp/separator_middle.png
new file mode 100755 (executable)
index 0000000..9e3ab0e
Binary files /dev/null and b/xui/imp/separator_middle.png differ
diff --git a/xui/imp/separator_right.png b/xui/imp/separator_right.png
new file mode 100755 (executable)
index 0000000..34f1936
Binary files /dev/null and b/xui/imp/separator_right.png differ
diff --git a/xui/imp/status_left.png b/xui/imp/status_left.png
new file mode 100755 (executable)
index 0000000..9ab40e4
Binary files /dev/null and b/xui/imp/status_left.png differ
diff --git a/xui/imp/status_lower.png b/xui/imp/status_lower.png
new file mode 100755 (executable)
index 0000000..df5aac9
Binary files /dev/null and b/xui/imp/status_lower.png differ
diff --git a/xui/imp/status_lower_left.png b/xui/imp/status_lower_left.png
new file mode 100755 (executable)
index 0000000..02247af
Binary files /dev/null and b/xui/imp/status_lower_left.png differ
diff --git a/xui/imp/status_lower_right.png b/xui/imp/status_lower_right.png
new file mode 100755 (executable)
index 0000000..ce9f6d6
Binary files /dev/null and b/xui/imp/status_lower_right.png differ
diff --git a/xui/imp/status_middle.png b/xui/imp/status_middle.png
new file mode 100755 (executable)
index 0000000..9344b80
Binary files /dev/null and b/xui/imp/status_middle.png differ
diff --git a/xui/imp/status_right.png b/xui/imp/status_right.png
new file mode 100755 (executable)
index 0000000..9ab40e4
Binary files /dev/null and b/xui/imp/status_right.png differ
diff --git a/xui/imp/status_upper.png b/xui/imp/status_upper.png
new file mode 100755 (executable)
index 0000000..df5aac9
Binary files /dev/null and b/xui/imp/status_upper.png differ
diff --git a/xui/imp/status_upper_left.png b/xui/imp/status_upper_left.png
new file mode 100755 (executable)
index 0000000..dfb727f
Binary files /dev/null and b/xui/imp/status_upper_left.png differ
diff --git a/xui/imp/status_upper_right.png b/xui/imp/status_upper_right.png
new file mode 100755 (executable)
index 0000000..618735b
Binary files /dev/null and b/xui/imp/status_upper_right.png differ
diff --git a/xui/imp/tiny_fill_bar_base.png b/xui/imp/tiny_fill_bar_base.png
new file mode 100755 (executable)
index 0000000..1d269a3
Binary files /dev/null and b/xui/imp/tiny_fill_bar_base.png differ
diff --git a/xui/imp/tiny_fill_bar_left.png b/xui/imp/tiny_fill_bar_left.png
new file mode 100755 (executable)
index 0000000..273075a
Binary files /dev/null and b/xui/imp/tiny_fill_bar_left.png differ
diff --git a/xui/imp/tiny_fill_bar_middle.png b/xui/imp/tiny_fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..714591c
Binary files /dev/null and b/xui/imp/tiny_fill_bar_middle.png differ
diff --git a/xui/imp/tiny_fill_bar_right.png b/xui/imp/tiny_fill_bar_right.png
new file mode 100755 (executable)
index 0000000..46e5b5f
Binary files /dev/null and b/xui/imp/tiny_fill_bar_right.png differ
diff --git a/xui/imp/title_bar_left.png b/xui/imp/title_bar_left.png
new file mode 100755 (executable)
index 0000000..0dd6e2c
Binary files /dev/null and b/xui/imp/title_bar_left.png differ
diff --git a/xui/imp/title_bar_middle.png b/xui/imp/title_bar_middle.png
new file mode 100755 (executable)
index 0000000..444f836
Binary files /dev/null and b/xui/imp/title_bar_middle.png differ
diff --git a/xui/imp/title_bar_right.png b/xui/imp/title_bar_right.png
new file mode 100755 (executable)
index 0000000..885cf7d
Binary files /dev/null and b/xui/imp/title_bar_right.png differ
diff --git a/xui/imp/ubericon_frame.png b/xui/imp/ubericon_frame.png
new file mode 100755 (executable)
index 0000000..632db4d
Binary files /dev/null and b/xui/imp/ubericon_frame.png differ
diff --git a/xui/imp/window_left.png b/xui/imp/window_left.png
new file mode 100755 (executable)
index 0000000..8657ad3
Binary files /dev/null and b/xui/imp/window_left.png differ
diff --git a/xui/imp/window_lower.png b/xui/imp/window_lower.png
new file mode 100755 (executable)
index 0000000..e6680fa
Binary files /dev/null and b/xui/imp/window_lower.png differ
diff --git a/xui/imp/window_lower_left.png b/xui/imp/window_lower_left.png
new file mode 100755 (executable)
index 0000000..131f1bd
Binary files /dev/null and b/xui/imp/window_lower_left.png differ
diff --git a/xui/imp/window_lower_right.png b/xui/imp/window_lower_right.png
new file mode 100755 (executable)
index 0000000..c949d66
Binary files /dev/null and b/xui/imp/window_lower_right.png differ
diff --git a/xui/imp/window_right.png b/xui/imp/window_right.png
new file mode 100755 (executable)
index 0000000..8657ad3
Binary files /dev/null and b/xui/imp/window_right.png differ
diff --git a/xui/imp/window_upper.png b/xui/imp/window_upper.png
new file mode 100755 (executable)
index 0000000..e43d561
Binary files /dev/null and b/xui/imp/window_upper.png differ
diff --git a/xui/imp/window_upper_left.png b/xui/imp/window_upper_left.png
new file mode 100755 (executable)
index 0000000..5bdd80c
Binary files /dev/null and b/xui/imp/window_upper_left.png differ
diff --git a/xui/imp/window_upper_right.png b/xui/imp/window_upper_right.png
new file mode 100755 (executable)
index 0000000..f72c9e1
Binary files /dev/null and b/xui/imp/window_upper_right.png differ
diff --git a/xui/kobold/button_left.png b/xui/kobold/button_left.png
new file mode 100755 (executable)
index 0000000..459c94e
Binary files /dev/null and b/xui/kobold/button_left.png differ
diff --git a/xui/kobold/button_lower.png b/xui/kobold/button_lower.png
new file mode 100755 (executable)
index 0000000..5f975d5
Binary files /dev/null and b/xui/kobold/button_lower.png differ
diff --git a/xui/kobold/button_lower_left.png b/xui/kobold/button_lower_left.png
new file mode 100755 (executable)
index 0000000..8eea2c7
Binary files /dev/null and b/xui/kobold/button_lower_left.png differ
diff --git a/xui/kobold/button_lower_right.png b/xui/kobold/button_lower_right.png
new file mode 100755 (executable)
index 0000000..d634f51
Binary files /dev/null and b/xui/kobold/button_lower_right.png differ
diff --git a/xui/kobold/button_middle.png b/xui/kobold/button_middle.png
new file mode 100755 (executable)
index 0000000..56941d0
Binary files /dev/null and b/xui/kobold/button_middle.png differ
diff --git a/xui/kobold/button_right.png b/xui/kobold/button_right.png
new file mode 100755 (executable)
index 0000000..d99f39c
Binary files /dev/null and b/xui/kobold/button_right.png differ
diff --git a/xui/kobold/button_upper.png b/xui/kobold/button_upper.png
new file mode 100755 (executable)
index 0000000..7913dd2
Binary files /dev/null and b/xui/kobold/button_upper.png differ
diff --git a/xui/kobold/button_upper_left.png b/xui/kobold/button_upper_left.png
new file mode 100755 (executable)
index 0000000..8645a96
Binary files /dev/null and b/xui/kobold/button_upper_left.png differ
diff --git a/xui/kobold/button_upper_right.png b/xui/kobold/button_upper_right.png
new file mode 100755 (executable)
index 0000000..88314ab
Binary files /dev/null and b/xui/kobold/button_upper_right.png differ
diff --git a/xui/kobold/check_box_off.png b/xui/kobold/check_box_off.png
new file mode 100755 (executable)
index 0000000..67ade15
Binary files /dev/null and b/xui/kobold/check_box_off.png differ
diff --git a/xui/kobold/check_box_on.png b/xui/kobold/check_box_on.png
new file mode 100755 (executable)
index 0000000..a4a348c
Binary files /dev/null and b/xui/kobold/check_box_on.png differ
diff --git a/xui/kobold/cursor.png b/xui/kobold/cursor.png
new file mode 100755 (executable)
index 0000000..642d25f
Binary files /dev/null and b/xui/kobold/cursor.png differ
diff --git a/xui/kobold/end_turn_button.png b/xui/kobold/end_turn_button.png
new file mode 100755 (executable)
index 0000000..d758401
Binary files /dev/null and b/xui/kobold/end_turn_button.png differ
diff --git a/xui/kobold/fill_bar_base.png b/xui/kobold/fill_bar_base.png
new file mode 100755 (executable)
index 0000000..9700b8d
Binary files /dev/null and b/xui/kobold/fill_bar_base.png differ
diff --git a/xui/kobold/fill_bar_left.png b/xui/kobold/fill_bar_left.png
new file mode 100755 (executable)
index 0000000..f476e09
Binary files /dev/null and b/xui/kobold/fill_bar_left.png differ
diff --git a/xui/kobold/fill_bar_middle.png b/xui/kobold/fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..7925164
Binary files /dev/null and b/xui/kobold/fill_bar_middle.png differ
diff --git a/xui/kobold/fill_bar_right.png b/xui/kobold/fill_bar_right.png
new file mode 100755 (executable)
index 0000000..186aeef
Binary files /dev/null and b/xui/kobold/fill_bar_right.png differ
diff --git a/xui/kobold/frame_left.png b/xui/kobold/frame_left.png
new file mode 100755 (executable)
index 0000000..2992c77
Binary files /dev/null and b/xui/kobold/frame_left.png differ
diff --git a/xui/kobold/frame_lower.png b/xui/kobold/frame_lower.png
new file mode 100755 (executable)
index 0000000..595cc28
Binary files /dev/null and b/xui/kobold/frame_lower.png differ
diff --git a/xui/kobold/frame_lower_left.png b/xui/kobold/frame_lower_left.png
new file mode 100755 (executable)
index 0000000..a9be1d1
Binary files /dev/null and b/xui/kobold/frame_lower_left.png differ
diff --git a/xui/kobold/frame_lower_right.png b/xui/kobold/frame_lower_right.png
new file mode 100755 (executable)
index 0000000..cc665d9
Binary files /dev/null and b/xui/kobold/frame_lower_right.png differ
diff --git a/xui/kobold/frame_right.png b/xui/kobold/frame_right.png
new file mode 100755 (executable)
index 0000000..237f05c
Binary files /dev/null and b/xui/kobold/frame_right.png differ
diff --git a/xui/kobold/frame_upper.png b/xui/kobold/frame_upper.png
new file mode 100755 (executable)
index 0000000..df9b88d
Binary files /dev/null and b/xui/kobold/frame_upper.png differ
diff --git a/xui/kobold/frame_upper_left.png b/xui/kobold/frame_upper_left.png
new file mode 100755 (executable)
index 0000000..c6ffbf3
Binary files /dev/null and b/xui/kobold/frame_upper_left.png differ
diff --git a/xui/kobold/frame_upper_right.png b/xui/kobold/frame_upper_right.png
new file mode 100755 (executable)
index 0000000..7dde0ca
Binary files /dev/null and b/xui/kobold/frame_upper_right.png differ
diff --git a/xui/kobold/icon_frame.png b/xui/kobold/icon_frame.png
new file mode 100755 (executable)
index 0000000..91d28b4
Binary files /dev/null and b/xui/kobold/icon_frame.png differ
diff --git a/xui/kobold/menu_left.png b/xui/kobold/menu_left.png
new file mode 100755 (executable)
index 0000000..b03f501
Binary files /dev/null and b/xui/kobold/menu_left.png differ
diff --git a/xui/kobold/menu_lower.png b/xui/kobold/menu_lower.png
new file mode 100755 (executable)
index 0000000..f66da0f
Binary files /dev/null and b/xui/kobold/menu_lower.png differ
diff --git a/xui/kobold/menu_lower_left.png b/xui/kobold/menu_lower_left.png
new file mode 100755 (executable)
index 0000000..bd5992a
Binary files /dev/null and b/xui/kobold/menu_lower_left.png differ
diff --git a/xui/kobold/menu_lower_right.png b/xui/kobold/menu_lower_right.png
new file mode 100755 (executable)
index 0000000..8bcfeeb
Binary files /dev/null and b/xui/kobold/menu_lower_right.png differ
diff --git a/xui/kobold/menu_middle.png b/xui/kobold/menu_middle.png
new file mode 100755 (executable)
index 0000000..a26fbaf
Binary files /dev/null and b/xui/kobold/menu_middle.png differ
diff --git a/xui/kobold/menu_right.png b/xui/kobold/menu_right.png
new file mode 100755 (executable)
index 0000000..f94d669
Binary files /dev/null and b/xui/kobold/menu_right.png differ
diff --git a/xui/kobold/menu_upper.png b/xui/kobold/menu_upper.png
new file mode 100755 (executable)
index 0000000..ca8f63f
Binary files /dev/null and b/xui/kobold/menu_upper.png differ
diff --git a/xui/kobold/menu_upper_left.png b/xui/kobold/menu_upper_left.png
new file mode 100755 (executable)
index 0000000..ecbe19c
Binary files /dev/null and b/xui/kobold/menu_upper_left.png differ
diff --git a/xui/kobold/menu_upper_right.png b/xui/kobold/menu_upper_right.png
new file mode 100755 (executable)
index 0000000..deca995
Binary files /dev/null and b/xui/kobold/menu_upper_right.png differ
diff --git a/xui/kobold/overicon_frame.png b/xui/kobold/overicon_frame.png
new file mode 100755 (executable)
index 0000000..f02a9e0
Binary files /dev/null and b/xui/kobold/overicon_frame.png differ
diff --git a/xui/kobold/scroll_bar_lower.png b/xui/kobold/scroll_bar_lower.png
new file mode 100755 (executable)
index 0000000..67755e3
Binary files /dev/null and b/xui/kobold/scroll_bar_lower.png differ
diff --git a/xui/kobold/scroll_bar_middle.png b/xui/kobold/scroll_bar_middle.png
new file mode 100755 (executable)
index 0000000..84ca0b2
Binary files /dev/null and b/xui/kobold/scroll_bar_middle.png differ
diff --git a/xui/kobold/scroll_bar_slider.png b/xui/kobold/scroll_bar_slider.png
new file mode 100755 (executable)
index 0000000..67ade15
Binary files /dev/null and b/xui/kobold/scroll_bar_slider.png differ
diff --git a/xui/kobold/scroll_bar_upper.png b/xui/kobold/scroll_bar_upper.png
new file mode 100755 (executable)
index 0000000..1f1ac5a
Binary files /dev/null and b/xui/kobold/scroll_bar_upper.png differ
diff --git a/xui/kobold/separator_center.png b/xui/kobold/separator_center.png
new file mode 100755 (executable)
index 0000000..67ade15
Binary files /dev/null and b/xui/kobold/separator_center.png differ
diff --git a/xui/kobold/separator_left.png b/xui/kobold/separator_left.png
new file mode 100755 (executable)
index 0000000..fcca2e2
Binary files /dev/null and b/xui/kobold/separator_left.png differ
diff --git a/xui/kobold/separator_middle.png b/xui/kobold/separator_middle.png
new file mode 100755 (executable)
index 0000000..3fd8a18
Binary files /dev/null and b/xui/kobold/separator_middle.png differ
diff --git a/xui/kobold/separator_right.png b/xui/kobold/separator_right.png
new file mode 100755 (executable)
index 0000000..d0c1ff7
Binary files /dev/null and b/xui/kobold/separator_right.png differ
diff --git a/xui/kobold/status_left.png b/xui/kobold/status_left.png
new file mode 100755 (executable)
index 0000000..5a0b0cd
Binary files /dev/null and b/xui/kobold/status_left.png differ
diff --git a/xui/kobold/status_lower.png b/xui/kobold/status_lower.png
new file mode 100755 (executable)
index 0000000..f4a3428
Binary files /dev/null and b/xui/kobold/status_lower.png differ
diff --git a/xui/kobold/status_lower_left.png b/xui/kobold/status_lower_left.png
new file mode 100755 (executable)
index 0000000..3d3061a
Binary files /dev/null and b/xui/kobold/status_lower_left.png differ
diff --git a/xui/kobold/status_lower_right.png b/xui/kobold/status_lower_right.png
new file mode 100755 (executable)
index 0000000..4db83b4
Binary files /dev/null and b/xui/kobold/status_lower_right.png differ
diff --git a/xui/kobold/status_middle.png b/xui/kobold/status_middle.png
new file mode 100755 (executable)
index 0000000..fc8774a
Binary files /dev/null and b/xui/kobold/status_middle.png differ
diff --git a/xui/kobold/status_right.png b/xui/kobold/status_right.png
new file mode 100755 (executable)
index 0000000..2b47206
Binary files /dev/null and b/xui/kobold/status_right.png differ
diff --git a/xui/kobold/status_upper.png b/xui/kobold/status_upper.png
new file mode 100755 (executable)
index 0000000..8ba8817
Binary files /dev/null and b/xui/kobold/status_upper.png differ
diff --git a/xui/kobold/status_upper_left.png b/xui/kobold/status_upper_left.png
new file mode 100755 (executable)
index 0000000..4db83b4
Binary files /dev/null and b/xui/kobold/status_upper_left.png differ
diff --git a/xui/kobold/status_upper_right.png b/xui/kobold/status_upper_right.png
new file mode 100755 (executable)
index 0000000..616a8b5
Binary files /dev/null and b/xui/kobold/status_upper_right.png differ
diff --git a/xui/kobold/tiny_fill_bar_base.png b/xui/kobold/tiny_fill_bar_base.png
new file mode 100755 (executable)
index 0000000..e2e8b91
Binary files /dev/null and b/xui/kobold/tiny_fill_bar_base.png differ
diff --git a/xui/kobold/tiny_fill_bar_left.png b/xui/kobold/tiny_fill_bar_left.png
new file mode 100755 (executable)
index 0000000..72cd6af
Binary files /dev/null and b/xui/kobold/tiny_fill_bar_left.png differ
diff --git a/xui/kobold/tiny_fill_bar_middle.png b/xui/kobold/tiny_fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..481637c
Binary files /dev/null and b/xui/kobold/tiny_fill_bar_middle.png differ
diff --git a/xui/kobold/tiny_fill_bar_right.png b/xui/kobold/tiny_fill_bar_right.png
new file mode 100755 (executable)
index 0000000..17ba645
Binary files /dev/null and b/xui/kobold/tiny_fill_bar_right.png differ
diff --git a/xui/kobold/title_bar_left.png b/xui/kobold/title_bar_left.png
new file mode 100755 (executable)
index 0000000..d60d30c
Binary files /dev/null and b/xui/kobold/title_bar_left.png differ
diff --git a/xui/kobold/title_bar_middle.png b/xui/kobold/title_bar_middle.png
new file mode 100755 (executable)
index 0000000..9553b37
Binary files /dev/null and b/xui/kobold/title_bar_middle.png differ
diff --git a/xui/kobold/title_bar_right.png b/xui/kobold/title_bar_right.png
new file mode 100755 (executable)
index 0000000..4042ee7
Binary files /dev/null and b/xui/kobold/title_bar_right.png differ
diff --git a/xui/kobold/ubericon_frame.png b/xui/kobold/ubericon_frame.png
new file mode 100755 (executable)
index 0000000..73d3ab9
Binary files /dev/null and b/xui/kobold/ubericon_frame.png differ
diff --git a/xui/kobold/window_left.png b/xui/kobold/window_left.png
new file mode 100755 (executable)
index 0000000..f3b9c57
Binary files /dev/null and b/xui/kobold/window_left.png differ
diff --git a/xui/kobold/window_lower.png b/xui/kobold/window_lower.png
new file mode 100755 (executable)
index 0000000..aa024d6
Binary files /dev/null and b/xui/kobold/window_lower.png differ
diff --git a/xui/kobold/window_lower_left.png b/xui/kobold/window_lower_left.png
new file mode 100755 (executable)
index 0000000..10fa07f
Binary files /dev/null and b/xui/kobold/window_lower_left.png differ
diff --git a/xui/kobold/window_lower_right.png b/xui/kobold/window_lower_right.png
new file mode 100755 (executable)
index 0000000..d2f38c0
Binary files /dev/null and b/xui/kobold/window_lower_right.png differ
diff --git a/xui/kobold/window_right.png b/xui/kobold/window_right.png
new file mode 100755 (executable)
index 0000000..8d308cd
Binary files /dev/null and b/xui/kobold/window_right.png differ
diff --git a/xui/kobold/window_upper.png b/xui/kobold/window_upper.png
new file mode 100755 (executable)
index 0000000..de0988f
Binary files /dev/null and b/xui/kobold/window_upper.png differ
diff --git a/xui/kobold/window_upper_left.png b/xui/kobold/window_upper_left.png
new file mode 100755 (executable)
index 0000000..9db4b46
Binary files /dev/null and b/xui/kobold/window_upper_left.png differ
diff --git a/xui/kobold/window_upper_right.png b/xui/kobold/window_upper_right.png
new file mode 100755 (executable)
index 0000000..22c0a6f
Binary files /dev/null and b/xui/kobold/window_upper_right.png differ
diff --git a/xui/main/button_left.png b/xui/main/button_left.png
new file mode 100755 (executable)
index 0000000..1eab978
Binary files /dev/null and b/xui/main/button_left.png differ
diff --git a/xui/main/button_lower.png b/xui/main/button_lower.png
new file mode 100755 (executable)
index 0000000..8cde9ed
Binary files /dev/null and b/xui/main/button_lower.png differ
diff --git a/xui/main/button_lower_left.png b/xui/main/button_lower_left.png
new file mode 100755 (executable)
index 0000000..4cc4d88
Binary files /dev/null and b/xui/main/button_lower_left.png differ
diff --git a/xui/main/button_lower_right.png b/xui/main/button_lower_right.png
new file mode 100755 (executable)
index 0000000..67631b3
Binary files /dev/null and b/xui/main/button_lower_right.png differ
diff --git a/xui/main/button_middle.png b/xui/main/button_middle.png
new file mode 100755 (executable)
index 0000000..e59eec4
Binary files /dev/null and b/xui/main/button_middle.png differ
diff --git a/xui/main/button_right.png b/xui/main/button_right.png
new file mode 100755 (executable)
index 0000000..ecfe5f5
Binary files /dev/null and b/xui/main/button_right.png differ
diff --git a/xui/main/button_upper.png b/xui/main/button_upper.png
new file mode 100755 (executable)
index 0000000..58fa8d1
Binary files /dev/null and b/xui/main/button_upper.png differ
diff --git a/xui/main/button_upper_left.png b/xui/main/button_upper_left.png
new file mode 100755 (executable)
index 0000000..84850a2
Binary files /dev/null and b/xui/main/button_upper_left.png differ
diff --git a/xui/main/button_upper_right.png b/xui/main/button_upper_right.png
new file mode 100755 (executable)
index 0000000..32b1787
Binary files /dev/null and b/xui/main/button_upper_right.png differ
diff --git a/xui/main/check_box_off.png b/xui/main/check_box_off.png
new file mode 100755 (executable)
index 0000000..62aad2c
Binary files /dev/null and b/xui/main/check_box_off.png differ
diff --git a/xui/main/check_box_on.png b/xui/main/check_box_on.png
new file mode 100755 (executable)
index 0000000..46d48ee
Binary files /dev/null and b/xui/main/check_box_on.png differ
diff --git a/xui/main/cursor.png b/xui/main/cursor.png
new file mode 100755 (executable)
index 0000000..d2df188
Binary files /dev/null and b/xui/main/cursor.png differ
diff --git a/xui/main/end_turn_button.png b/xui/main/end_turn_button.png
new file mode 100755 (executable)
index 0000000..62e857b
Binary files /dev/null and b/xui/main/end_turn_button.png differ
diff --git a/xui/main/fill_bar_base.png b/xui/main/fill_bar_base.png
new file mode 100755 (executable)
index 0000000..a00e65c
Binary files /dev/null and b/xui/main/fill_bar_base.png differ
diff --git a/xui/main/fill_bar_left.png b/xui/main/fill_bar_left.png
new file mode 100755 (executable)
index 0000000..718b784
Binary files /dev/null and b/xui/main/fill_bar_left.png differ
diff --git a/xui/main/fill_bar_middle.png b/xui/main/fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..09c7742
Binary files /dev/null and b/xui/main/fill_bar_middle.png differ
diff --git a/xui/main/fill_bar_right.png b/xui/main/fill_bar_right.png
new file mode 100755 (executable)
index 0000000..7b0d2b3
Binary files /dev/null and b/xui/main/fill_bar_right.png differ
diff --git a/xui/main/frame_left.png b/xui/main/frame_left.png
new file mode 100755 (executable)
index 0000000..a2a958a
Binary files /dev/null and b/xui/main/frame_left.png differ
diff --git a/xui/main/frame_lower.png b/xui/main/frame_lower.png
new file mode 100755 (executable)
index 0000000..81ca5e6
Binary files /dev/null and b/xui/main/frame_lower.png differ
diff --git a/xui/main/frame_lower_left.png b/xui/main/frame_lower_left.png
new file mode 100755 (executable)
index 0000000..a72209e
Binary files /dev/null and b/xui/main/frame_lower_left.png differ
diff --git a/xui/main/frame_lower_right.png b/xui/main/frame_lower_right.png
new file mode 100755 (executable)
index 0000000..e6ce5ef
Binary files /dev/null and b/xui/main/frame_lower_right.png differ
diff --git a/xui/main/frame_right.png b/xui/main/frame_right.png
new file mode 100755 (executable)
index 0000000..f13c0c1
Binary files /dev/null and b/xui/main/frame_right.png differ
diff --git a/xui/main/frame_upper.png b/xui/main/frame_upper.png
new file mode 100755 (executable)
index 0000000..1836052
Binary files /dev/null and b/xui/main/frame_upper.png differ
diff --git a/xui/main/frame_upper_left.png b/xui/main/frame_upper_left.png
new file mode 100755 (executable)
index 0000000..0ceca8d
Binary files /dev/null and b/xui/main/frame_upper_left.png differ
diff --git a/xui/main/frame_upper_right.png b/xui/main/frame_upper_right.png
new file mode 100755 (executable)
index 0000000..9e81eb0
Binary files /dev/null and b/xui/main/frame_upper_right.png differ
diff --git a/xui/main/icon_frame.png b/xui/main/icon_frame.png
new file mode 100755 (executable)
index 0000000..0f1db5c
Binary files /dev/null and b/xui/main/icon_frame.png differ
diff --git a/xui/main/menu_left.png b/xui/main/menu_left.png
new file mode 100755 (executable)
index 0000000..ad04d19
Binary files /dev/null and b/xui/main/menu_left.png differ
diff --git a/xui/main/menu_lower.png b/xui/main/menu_lower.png
new file mode 100755 (executable)
index 0000000..664e550
Binary files /dev/null and b/xui/main/menu_lower.png differ
diff --git a/xui/main/menu_lower_left.png b/xui/main/menu_lower_left.png
new file mode 100755 (executable)
index 0000000..6a45100
Binary files /dev/null and b/xui/main/menu_lower_left.png differ
diff --git a/xui/main/menu_lower_right.png b/xui/main/menu_lower_right.png
new file mode 100755 (executable)
index 0000000..8fb6a26
Binary files /dev/null and b/xui/main/menu_lower_right.png differ
diff --git a/xui/main/menu_middle.png b/xui/main/menu_middle.png
new file mode 100755 (executable)
index 0000000..687c3c2
Binary files /dev/null and b/xui/main/menu_middle.png differ
diff --git a/xui/main/menu_right.png b/xui/main/menu_right.png
new file mode 100755 (executable)
index 0000000..0901983
Binary files /dev/null and b/xui/main/menu_right.png differ
diff --git a/xui/main/menu_upper.png b/xui/main/menu_upper.png
new file mode 100755 (executable)
index 0000000..1468519
Binary files /dev/null and b/xui/main/menu_upper.png differ
diff --git a/xui/main/menu_upper_left.png b/xui/main/menu_upper_left.png
new file mode 100755 (executable)
index 0000000..7f50d67
Binary files /dev/null and b/xui/main/menu_upper_left.png differ
diff --git a/xui/main/menu_upper_right.png b/xui/main/menu_upper_right.png
new file mode 100755 (executable)
index 0000000..5237243
Binary files /dev/null and b/xui/main/menu_upper_right.png differ
diff --git a/xui/main/overicon_frame.png b/xui/main/overicon_frame.png
new file mode 100755 (executable)
index 0000000..44a13fa
Binary files /dev/null and b/xui/main/overicon_frame.png differ
diff --git a/xui/main/scroll_bar_lower.png b/xui/main/scroll_bar_lower.png
new file mode 100755 (executable)
index 0000000..6ae9c44
Binary files /dev/null and b/xui/main/scroll_bar_lower.png differ
diff --git a/xui/main/scroll_bar_middle.png b/xui/main/scroll_bar_middle.png
new file mode 100755 (executable)
index 0000000..734c732
Binary files /dev/null and b/xui/main/scroll_bar_middle.png differ
diff --git a/xui/main/scroll_bar_slider.png b/xui/main/scroll_bar_slider.png
new file mode 100755 (executable)
index 0000000..62aad2c
Binary files /dev/null and b/xui/main/scroll_bar_slider.png differ
diff --git a/xui/main/scroll_bar_upper.png b/xui/main/scroll_bar_upper.png
new file mode 100755 (executable)
index 0000000..81fba3c
Binary files /dev/null and b/xui/main/scroll_bar_upper.png differ
diff --git a/xui/main/separator_center.png b/xui/main/separator_center.png
new file mode 100755 (executable)
index 0000000..62aad2c
Binary files /dev/null and b/xui/main/separator_center.png differ
diff --git a/xui/main/separator_left.png b/xui/main/separator_left.png
new file mode 100755 (executable)
index 0000000..728d4ff
Binary files /dev/null and b/xui/main/separator_left.png differ
diff --git a/xui/main/separator_middle.png b/xui/main/separator_middle.png
new file mode 100755 (executable)
index 0000000..d14912e
Binary files /dev/null and b/xui/main/separator_middle.png differ
diff --git a/xui/main/separator_right.png b/xui/main/separator_right.png
new file mode 100755 (executable)
index 0000000..6481f60
Binary files /dev/null and b/xui/main/separator_right.png differ
diff --git a/xui/main/status_left.png b/xui/main/status_left.png
new file mode 100755 (executable)
index 0000000..ecd9b46
Binary files /dev/null and b/xui/main/status_left.png differ
diff --git a/xui/main/status_lower.png b/xui/main/status_lower.png
new file mode 100755 (executable)
index 0000000..3a59006
Binary files /dev/null and b/xui/main/status_lower.png differ
diff --git a/xui/main/status_lower_left.png b/xui/main/status_lower_left.png
new file mode 100755 (executable)
index 0000000..d75c94a
Binary files /dev/null and b/xui/main/status_lower_left.png differ
diff --git a/xui/main/status_lower_right.png b/xui/main/status_lower_right.png
new file mode 100755 (executable)
index 0000000..e0cda06
Binary files /dev/null and b/xui/main/status_lower_right.png differ
diff --git a/xui/main/status_middle.png b/xui/main/status_middle.png
new file mode 100755 (executable)
index 0000000..bf70085
Binary files /dev/null and b/xui/main/status_middle.png differ
diff --git a/xui/main/status_right.png b/xui/main/status_right.png
new file mode 100755 (executable)
index 0000000..ecd9b46
Binary files /dev/null and b/xui/main/status_right.png differ
diff --git a/xui/main/status_upper.png b/xui/main/status_upper.png
new file mode 100755 (executable)
index 0000000..3a59006
Binary files /dev/null and b/xui/main/status_upper.png differ
diff --git a/xui/main/status_upper_left.png b/xui/main/status_upper_left.png
new file mode 100755 (executable)
index 0000000..a83439b
Binary files /dev/null and b/xui/main/status_upper_left.png differ
diff --git a/xui/main/status_upper_right.png b/xui/main/status_upper_right.png
new file mode 100755 (executable)
index 0000000..ac1a9e2
Binary files /dev/null and b/xui/main/status_upper_right.png differ
diff --git a/xui/main/tiny_fill_bar_base.png b/xui/main/tiny_fill_bar_base.png
new file mode 100755 (executable)
index 0000000..338b4a0
Binary files /dev/null and b/xui/main/tiny_fill_bar_base.png differ
diff --git a/xui/main/tiny_fill_bar_left.png b/xui/main/tiny_fill_bar_left.png
new file mode 100755 (executable)
index 0000000..0017889
Binary files /dev/null and b/xui/main/tiny_fill_bar_left.png differ
diff --git a/xui/main/tiny_fill_bar_middle.png b/xui/main/tiny_fill_bar_middle.png
new file mode 100755 (executable)
index 0000000..bd35d5a
Binary files /dev/null and b/xui/main/tiny_fill_bar_middle.png differ
diff --git a/xui/main/tiny_fill_bar_right.png b/xui/main/tiny_fill_bar_right.png
new file mode 100755 (executable)
index 0000000..1d0cfd5
Binary files /dev/null and b/xui/main/tiny_fill_bar_right.png differ
diff --git a/xui/main/title_bar_left.png b/xui/main/title_bar_left.png
new file mode 100755 (executable)
index 0000000..270bf4a
Binary files /dev/null and b/xui/main/title_bar_left.png differ
diff --git a/xui/main/title_bar_middle.png b/xui/main/title_bar_middle.png
new file mode 100755 (executable)
index 0000000..75ad065
Binary files /dev/null and b/xui/main/title_bar_middle.png differ
diff --git a/xui/main/title_bar_right.png b/xui/main/title_bar_right.png
new file mode 100755 (executable)
index 0000000..e2cf22d
Binary files /dev/null and b/xui/main/title_bar_right.png differ
diff --git a/xui/main/ubericon_frame.png b/xui/main/ubericon_frame.png
new file mode 100755 (executable)
index 0000000..f6907d3
Binary files /dev/null and b/xui/main/ubericon_frame.png differ
diff --git a/xui/main/window_left.png b/xui/main/window_left.png
new file mode 100755 (executable)
index 0000000..e87a3de
Binary files /dev/null and b/xui/main/window_left.png differ
diff --git a/xui/main/window_lower.png b/xui/main/window_lower.png
new file mode 100755 (executable)
index 0000000..09b9e7e
Binary files /dev/null and b/xui/main/window_lower.png differ
diff --git a/xui/main/window_lower_left.png b/xui/main/window_lower_left.png
new file mode 100755 (executable)
index 0000000..389a476
Binary files /dev/null and b/xui/main/window_lower_left.png differ
diff --git a/xui/main/window_lower_right.png b/xui/main/window_lower_right.png
new file mode 100755 (executable)
index 0000000..7584dfb
Binary files /dev/null and b/xui/main/window_lower_right.png differ
diff --git a/xui/main/window_right.png b/xui/main/window_right.png
new file mode 100755 (executable)
index 0000000..d41293a
Binary files /dev/null and b/xui/main/window_right.png differ
diff --git a/xui/main/window_upper.png b/xui/main/window_upper.png
new file mode 100755 (executable)
index 0000000..6f68fcf
Binary files /dev/null and b/xui/main/window_upper.png differ
diff --git a/xui/main/window_upper_left.png b/xui/main/window_upper_left.png
new file mode 100755 (executable)
index 0000000..e43fc73
Binary files /dev/null and b/xui/main/window_upper_left.png differ
diff --git a/xui/main/window_upper_right.png b/xui/main/window_upper_right.png
new file mode 100755 (executable)
index 0000000..be10a83
Binary files /dev/null and b/xui/main/window_upper_right.png differ
diff --git a/xui/map_preview_panel_off.png b/xui/map_preview_panel_off.png
new file mode 100755 (executable)
index 0000000..d0fb58a
Binary files /dev/null and b/xui/map_preview_panel_off.png differ
diff --git a/xui/map_preview_panel_on.png b/xui/map_preview_panel_on.png
new file mode 100755 (executable)
index 0000000..08dd569
Binary files /dev/null and b/xui/map_preview_panel_on.png differ
diff --git a/xui/monospace.png b/xui/monospace.png
new file mode 100755 (executable)
index 0000000..074f192
Binary files /dev/null and b/xui/monospace.png differ
diff --git a/xui/palette.png b/xui/palette.png
new file mode 100755 (executable)
index 0000000..8a8ab27
Binary files /dev/null and b/xui/palette.png differ
diff --git a/xui/regular.png b/xui/regular.png
new file mode 100755 (executable)
index 0000000..0e5bfe7
Binary files /dev/null and b/xui/regular.png differ
diff --git a/xui/status_preview_panel_off.png b/xui/status_preview_panel_off.png
new file mode 100755 (executable)
index 0000000..fdb5173
Binary files /dev/null and b/xui/status_preview_panel_off.png differ
diff --git a/xui/status_preview_panel_on.png b/xui/status_preview_panel_on.png
new file mode 100755 (executable)
index 0000000..530fc12
Binary files /dev/null and b/xui/status_preview_panel_on.png differ
diff --git a/xui/text_box_panel_off.png b/xui/text_box_panel_off.png
new file mode 100755 (executable)
index 0000000..06efe6c
Binary files /dev/null and b/xui/text_box_panel_off.png differ
diff --git a/xui/text_box_panel_on.png b/xui/text_box_panel_on.png
new file mode 100755 (executable)
index 0000000..0576c96
Binary files /dev/null and b/xui/text_box_panel_on.png differ
diff --git a/xulkan.h b/xulkan.h
new file mode 100755 (executable)
index 0000000..4a3b2fc
--- /dev/null
+++ b/xulkan.h
@@ -0,0 +1,2351 @@
+///             _ _
+/// __  ___   _| | | ____ _ _ __
+/// \ \/ / | | | | |/ / _` | '_ \
+///  >  <| |_| | |   < (_| | | | |
+/// /_/\_\\__,_|_|_|\_\__,_|_| |_|
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xulkan - Tiny and elegant Vulkan wrapper library so I don't have to write 40k lines of code for a triangle...
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+/// DO NOT USE THIS CRAP...
+
+#define VK_USE_PLATFORM_XCB_KHR
+
+#include <vulkan/vulkan.h>
+
+typedef struct {
+       bool active;
+       bool reconfigure_active;
+       bool validation_layers;
+       bool hide_cursor_full;
+       bool hide_cursor;
+       uint time;
+
+       uint cursor; /// TODO: PROPER INPUT
+       int  cursor_x;
+       int  cursor_y;
+
+       bool signal [signal_count];
+
+       float     pixel_width;
+       float     pixel_height;
+       uint      frame;
+       uint      width;
+       uint      height;
+       uint      sprite_count;
+       uint  * * sprite_data;
+       uint    * sprite_width;
+       uint    * sprite_height;
+       float   * sprite_u;
+       float   * sprite_v;
+       uint      font_count;
+       uint  * * font_index;
+       uint  * * font_width;
+       uint  * * font_height;
+       char    * font_begin;
+       char    * font_end;
+
+       xcb_connection_t * connection;
+       xcb_screen_t     * screen;
+       xcb_window_t       window;
+
+       uint  global_time;
+       uint  gameplay_time;
+       uint  animation_time;
+       uint  framerate;
+       uint  gameplay_framerate;
+       uint  animation_framerate;
+       ulong frame_time_in_ns;
+
+       VkInstance                      instance;
+       VkSurfaceKHR                    surface;
+       VkPhysicalDevice                physical_device;
+       VkQueue                         queue;
+       uint                            queue_index;
+       VkDevice                        logical_device;
+       uint                            image_count;
+       VkExtent2D                      extent;
+       VkFormat                        format;
+       VkPresentModeKHR                present_mode;
+       VkSurfaceTransformFlagBitsKHR   transform;
+       VkCompositeAlphaFlagBitsKHR     composite_alpha;
+       VkSwapchainKHR                  swapchain;
+       VkImage                       * images;
+       VkImageView                   * image_views;
+       VkSemaphore                   * semaphore_set_1;
+       VkSemaphore                   * semaphore_set_2;
+       VkFence                       * fence_set_1;
+       VkDescriptorSetLayout           descriptor_set_layout;
+       VkDescriptorSetLayout         * descriptor_set_layouts;
+       VkDescriptorPool                descriptor_pool;
+       VkDescriptorSet               * descriptor_sets;
+       VkRenderPass                    render_pass;
+       VkShaderModule                  vertex_shader;
+       VkShaderModule                  fragment_shader;
+       VkPipelineLayout                pipeline_layout;
+       VkPipeline                      pipeline;
+       VkFramebuffer                 * framebuffers;
+       VkCommandPool                   command_pool;
+       VkCommandBuffer               * command_buffers;
+       VkCommandBuffer                 transfer_buffer;
+       VkBuffer                        vertex_buffer;
+       VkDeviceMemory                  vertex_memory;
+       float                         * vertex_data;
+       VkDeviceSize                    vertex_size;
+       uint                            vertex_count;
+       uint                            vertex_limit;
+       VkBuffer                        index_buffer;
+       VkDeviceMemory                  index_memory;
+       uint                          * index_data;
+       VkDeviceSize                    index_size;
+       uint                            index_count;
+       uint                            index_limit;
+       VkSampler                       sampler;
+       VkImage                         layout_image;
+       VkDeviceMemory                  layout_memory;
+       VkImageView                     layout_image_view;
+       uint                          * layout_data;
+       uint                            layout_size;
+       uint                            layout_width;
+       uint                            layout_height;
+} vulkan_structure;
+
+static const char * vulkan_continue_execution [] = {
+       "/s Commands successfully completed.\n",
+       "/w Fence or query hasn't yet completed.\n",
+       "/w Wait operation hasn't completed in the specified time.\n",
+       "/w Event is signaled.\n",
+       "/w Event isn't signaled.\n",
+       "/w Return array was too small for the result.\n"
+};
+
+static const char * vulkan_break_execution [] = {
+       "/f Host memory allocation has failed.\n",
+       "/f Device memory allocation has failed.\n",
+       "/f Initialization of an object couldn't be completed.\n",
+       "/f Logical or physical device has been lost.\n",
+       "/f Mapping of a memory object has failed.\n",
+       "/f Requested layer isn't present or couln't be loaded.\n",
+       "/f Requested extension isn't supported.\n",
+       "/f Requested feature isn't supported.\n",
+       "/f Requested version of Vulkan isn't suported.\n",
+       "/f Too many objects of the type have alrady been created.\n",
+       "/f Requested format isn't supported.\n",
+       "/f Pool allocation has failed due to framentation.\n",
+       "/f Unknown error has occurred.\n",
+       "/f Undefined error has occured.\n"
+};
+
+static void vulkan_result (VkResult result) {
+       if (result == 0) {
+               return;
+       } else if (result > 0) {
+               print (vulkan_continue_execution [result]);
+       } else {
+               print (vulkan_break_execution [- result - 1]);
+               //~exit  (log_failure);
+       }
+}
+
+static vulkan_structure * vulkan_initialize (ulong quad_memory, ulong layout_side, uint gameplay_framerate, uint animation_framerate) {
+       vulkan_structure * vulkan = allocate (sizeof (* vulkan));
+
+       vulkan->vertex_limit        = quad_memory * 32;
+       vulkan->index_limit         = quad_memory * 6;
+       vulkan->gameplay_framerate  = gameplay_framerate;
+       vulkan->animation_framerate = animation_framerate;
+       vulkan->layout_width        = layout_side;
+       vulkan->layout_height       = layout_side;
+
+       return (vulkan);
+}
+
+static vulkan_structure * vulkan_deinitialize (vulkan_structure * vulkan) {
+       print ("/c Destroying and deallocating all the bullshit used so far...\n");
+
+       vulkan_result (vkQueueWaitIdle  (vulkan->queue));
+       vulkan_result (vkDeviceWaitIdle (vulkan->logical_device));
+
+       vulkan->sprite_width  = deallocate (vulkan->sprite_width);
+       vulkan->sprite_height = deallocate (vulkan->sprite_height);
+       vulkan->sprite_u      = deallocate (vulkan->sprite_u);
+       vulkan->sprite_v      = deallocate (vulkan->sprite_v);
+
+       if (vulkan->font_count > 0) {
+               for (uint index = 0; index < vulkan->font_count; ++index) {
+                       vulkan->font_index  [index] = deallocate (vulkan->font_index  [index]);
+                       vulkan->font_width  [index] = deallocate (vulkan->font_width  [index]);
+                       vulkan->font_height [index] = deallocate (vulkan->font_height [index]);
+               }
+
+               vulkan->font_index  = deallocate (vulkan->font_index);
+               vulkan->font_width  = deallocate (vulkan->font_width);
+               vulkan->font_height = deallocate (vulkan->font_height);
+               vulkan->font_begin  = deallocate (vulkan->font_begin);
+               vulkan->font_end    = deallocate (vulkan->font_end);
+       }
+
+       vkFreeDescriptorSets (vulkan->logical_device, vulkan->descriptor_pool, vulkan->image_count, vulkan->descriptor_sets);
+
+       vulkan->descriptor_set_layouts = deallocate (vulkan->descriptor_set_layouts);
+       vulkan->descriptor_sets        = deallocate (vulkan->descriptor_sets);
+
+       vkDestroyDescriptorPool (vulkan->logical_device, vulkan->descriptor_pool,   null);
+       vkDestroySampler        (vulkan->logical_device, vulkan->sampler,           null);
+       vkDestroyImageView      (vulkan->logical_device, vulkan->layout_image_view, null);
+       vkDestroyImage          (vulkan->logical_device, vulkan->layout_image,      null);
+       vkFreeMemory            (vulkan->logical_device, vulkan->layout_memory,     null);
+
+       vulkan->layout_data = deallocate (vulkan->layout_data);
+
+       vulkan->index_data  = deallocate (vulkan->index_data);
+       vulkan->vertex_data = deallocate (vulkan->vertex_data);
+/*
+       vkFreeCommandBuffers (vulkan->logical_device, vulkan->command_pool, vulkan->image_count, vulkan->command_buffers);
+*/
+       vulkan->command_buffers = deallocate (vulkan->command_buffers);
+
+       vkDestroyCommandPool (vulkan->logical_device, vulkan->command_pool, null);
+
+       for (uint index = 0; index < vulkan->image_count; ++index) {
+               vkDestroyFramebuffer (vulkan->logical_device, vulkan->framebuffers [index], null);
+       }
+
+       vulkan->framebuffers = deallocate (vulkan->framebuffers);
+
+       vkDestroyPipeline            (vulkan->logical_device, vulkan->pipeline,              null);
+       vkDestroyPipelineLayout      (vulkan->logical_device, vulkan->pipeline_layout,       null);
+       vkDestroyShaderModule        (vulkan->logical_device, vulkan->fragment_shader,       null);
+       vkDestroyShaderModule        (vulkan->logical_device, vulkan->vertex_shader,         null);
+       vkDestroyDescriptorSetLayout (vulkan->logical_device, vulkan->descriptor_set_layout, null);
+       vkDestroyRenderPass          (vulkan->logical_device, vulkan->render_pass,           null);
+
+       for (uint index = 0; index < vulkan->image_count; ++index) {
+               vkDestroySemaphore (vulkan->logical_device, vulkan->semaphore_set_1 [index], null);
+               vkDestroySemaphore (vulkan->logical_device, vulkan->semaphore_set_2 [index], null);
+               vkDestroyFence     (vulkan->logical_device, vulkan->fence_set_1     [index], null);
+       }
+
+       vulkan->semaphore_set_1 = deallocate (vulkan->semaphore_set_1);
+       vulkan->semaphore_set_2 = deallocate (vulkan->semaphore_set_2);
+       vulkan->fence_set_1     = deallocate (vulkan->fence_set_1);
+
+       for (uint index = 0; index < vulkan->image_count; ++index) {
+               vkDestroyImageView (vulkan->logical_device, vulkan->image_views [index], null);
+       }
+
+       vulkan->image_views = deallocate (vulkan->image_views);
+
+       vkDestroySwapchainKHR (vulkan->logical_device, vulkan->swapchain, null);
+
+       vulkan->images = deallocate (vulkan->images);
+
+       vkDestroySurfaceKHR (vulkan->instance, vulkan->surface, null);
+
+       vkDestroyDevice   (vulkan->logical_device, null);
+       vkDestroyInstance (vulkan->instance,       null);
+
+       xcb_destroy_window (vulkan->connection, vulkan->window);
+       xcb_disconnect     (vulkan->connection);
+
+       print ("/c Destroyed and deallocated all resources.\n");
+
+       return (deallocate (vulkan));
+}
+
+static uint vulkan_choose_memory_property (vulkan_structure * vulkan, uint wanted) {
+       uint index  = 0;
+       uint usable = 0;
+
+       VkPhysicalDeviceMemoryProperties memory_properties = { 0 };
+
+       vkGetPhysicalDeviceMemoryProperties (vulkan->physical_device, & memory_properties);
+
+       for (index = 0; index < memory_properties.memoryTypeCount; ++index) {
+               if ((memory_properties.memoryTypes [index].propertyFlags & wanted) == wanted) {
+                       usable &= (1 << index);
+               }
+       }
+
+       if (usable != wanted) {
+               print ("/w Can't set this memory property bit: usable = %i, wanted = %i.\n", usable, wanted);
+       }
+
+       return (usable);
+}
+
+static void vulkan_create_buffer (vulkan_structure * vulkan, VkBuffer * buffer, VkDeviceMemory * memory, VkDeviceSize size, VkMemoryPropertyFlags usage) {
+       uint wanted_memory_index = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+
+       VkBufferCreateInfo   buffer_information            = { 0 };
+       VkMemoryRequirements memory_requirements           = { 0 };
+       VkMemoryAllocateInfo memory_allocation_information = { 0 };
+
+       buffer_information.sType       = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+       buffer_information.size        = size;
+       buffer_information.usage       = usage;
+       buffer_information.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+
+       vulkan_result (vkCreateBuffer (vulkan->logical_device, & buffer_information, null, buffer));
+
+       vkGetBufferMemoryRequirements (vulkan->logical_device, * buffer, & memory_requirements);
+
+       memory_allocation_information.sType           = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+       memory_allocation_information.allocationSize  = memory_requirements.size;
+       memory_allocation_information.memoryTypeIndex = vulkan_choose_memory_property (vulkan, wanted_memory_index);
+
+       vulkan_result (vkAllocateMemory (vulkan->logical_device, & memory_allocation_information, null, memory));
+
+       vulkan_result (vkBindBufferMemory (vulkan->logical_device, * buffer, * memory, 0));
+}
+
+static void vulkan_begin_command_buffer (vulkan_structure * vulkan) {
+       VkCommandBufferAllocateInfo command_buffer_allocation_information = { 0 };
+       VkCommandBufferBeginInfo    command_buffer_begin_information      = { 0 };
+
+       command_buffer_allocation_information.sType              = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+       command_buffer_allocation_information.commandPool        = vulkan->command_pool;
+       command_buffer_allocation_information.level              = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+       command_buffer_allocation_information.commandBufferCount = 1;
+
+       command_buffer_begin_information.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+       command_buffer_begin_information.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+
+       vulkan_result (vkAllocateCommandBuffers (vulkan->logical_device, & command_buffer_allocation_information, & vulkan->transfer_buffer));
+
+       vulkan_result (vkBeginCommandBuffer (vulkan->transfer_buffer, & command_buffer_begin_information));
+}
+
+static void vulkan_end_command_buffer (vulkan_structure * vulkan) {
+       VkSubmitInfo submit_information = { 0 };
+
+       vkEndCommandBuffer (vulkan->transfer_buffer);
+
+       submit_information.sType              = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+       submit_information.commandBufferCount = 1;
+       submit_information.pCommandBuffers    = & vulkan->transfer_buffer;
+
+       vkQueueSubmit (vulkan->queue, 1, & submit_information, VK_NULL_HANDLE);
+
+       vkQueueWaitIdle (vulkan->queue);
+
+       vkFreeCommandBuffers (vulkan->logical_device, vulkan->command_pool, 1, & vulkan->transfer_buffer);
+
+       vulkan->transfer_buffer = VK_NULL_HANDLE;
+}
+
+static void vulkan_create_window (vulkan_structure * vulkan, const char * application) {
+       uint window_flags [2] = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       vulkan->connection = xcb_connect (null, null);
+
+       print ("Connected to /3X11 server/-.\n");
+
+       vulkan->screen = xcb_setup_roots_iterator (xcb_get_setup (vulkan->connection)).data;
+
+       vulkan->window = xcb_generate_id (vulkan->connection);
+
+       window_flags [0] = vulkan->screen->black_pixel;
+       window_flags [1] = XCB_EVENT_MASK_NO_EVENT         |
+                          XCB_EVENT_MASK_EXPOSURE         |
+                          /*XCB_EVENT_MASK_STRUCTURE_NOTIFY |*/
+                          XCB_EVENT_MASK_RESIZE_REDIRECT  |
+                          XCB_EVENT_MASK_KEY_RELEASE      |
+                          XCB_EVENT_MASK_KEY_PRESS        |
+                          /*XCB_EVENT_MASK_POINTER_MOTION   |*/
+                          XCB_EVENT_MASK_BUTTON_RELEASE   |
+                          XCB_EVENT_MASK_BUTTON_PRESS;
+
+       xcb_create_window (vulkan->connection, vulkan->screen->root_depth, vulkan->window, vulkan->screen->root, 0, 0,
+                          (ushort) vulkan->width, (ushort) vulkan->height, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT,
+                          vulkan->screen->root_visual, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, window_flags);
+
+       print ("/c Created /3XCB window/-.\n");
+
+       xcb_map_window (vulkan->connection, vulkan->window);
+
+       xcb_change_property (vulkan->connection, XCB_PROP_MODE_REPLACE, vulkan->window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8,
+                            string_length (application), application);
+
+       xcb_flush (vulkan->connection);
+
+       print ("Mapped /3XCB window/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_instance (vulkan_structure * vulkan, const char * application) {
+       uint current = 0;
+       uint general = 0;
+
+       VkApplicationInfo    application_information = { 0 };
+       VkInstanceCreateInfo instance_information    = { 0 };
+
+       uint                    instance_layer_count     = 0;
+       uint                  * instance_layer_index     = null;
+       VkLayerProperties     * instance_layer_array     = null;
+       uint                    instance_extension_count = 0;
+       uint                  * instance_extension_index = null;
+       VkExtensionProperties * instance_extension_array = null;
+
+       const uint default_instance_layer_count     = (uint) (vulkan->validation_layers == true);
+       const uint default_instance_extension_count = 2;
+
+       const char * default_instance_layer_array [VK_MAX_EXTENSION_NAME_SIZE] = {
+               "VK_LAYER_KHRONOS_validation"
+               //~"VK_LAYER_LUNARG_parameter_validation",
+               //~"VK_LAYER_LUNARG_core_validation",
+               //~"VK_LAYER_LUNARG_standard_validation"
+       };
+
+       const char * default_instance_extension_array [VK_MAX_EXTENSION_NAME_SIZE] = {
+               VK_KHR_SURFACE_EXTENSION_NAME,
+               VK_KHR_XCB_SURFACE_EXTENSION_NAME
+       };
+
+       vulkan->time = tick_tock ();
+
+       vulkan_result (vkEnumerateInstanceLayerProperties (& instance_layer_count, null));
+
+       print ("Instance layer count: /2%i/-\n", instance_layer_count);
+
+       instance_layer_index = allocate (instance_layer_count * sizeof (* instance_layer_index));
+       instance_layer_array = allocate (instance_layer_count * sizeof (* instance_layer_array));
+
+       vulkan_result (vkEnumerateInstanceLayerProperties (& instance_layer_count, instance_layer_array));
+
+       for (current = 0; current < instance_layer_count; ++current) {
+               for (general = 0; general < default_instance_layer_count; ++general) {
+                       if (string_compare (instance_layer_array [current].layerName, (char *) default_instance_layer_array [general])) {
+                               instance_layer_index [current] = true;
+                       }
+               }
+       }
+
+       for (current = 0; current < instance_layer_count; ++current) {
+               print ("\t[%t] %s\n", instance_layer_index [current], instance_layer_array [current].layerName);
+       }
+
+       instance_layer_index = deallocate (instance_layer_index);
+       instance_layer_array = deallocate (instance_layer_array);
+
+       print ("Enumerated /2instance layer properties/-.\n");
+
+       vulkan_result (vkEnumerateInstanceExtensionProperties (null, & instance_extension_count, null));
+
+       print ("Instance extension count: /2%i/-\n", instance_extension_count);
+
+       instance_extension_index = allocate (instance_extension_count * sizeof (* instance_extension_index));
+       instance_extension_array = allocate (instance_extension_count * sizeof (* instance_extension_array));
+
+       vulkan_result (vkEnumerateInstanceExtensionProperties (null, & instance_extension_count, instance_extension_array));
+
+       for (current = 0; current < instance_extension_count; ++current) {
+               for (general = 0; general < default_instance_extension_count; ++general) {
+                       if (string_compare (instance_extension_array [current].extensionName, (char *) default_instance_extension_array [general])) {
+                               instance_extension_index [current] = true;
+                       }
+               }
+       }
+
+       for (current = 0; current < instance_extension_count; ++current) {
+               print ("\t[%t] %s\n", instance_extension_index [current], instance_extension_array [current].extensionName);
+       }
+
+       instance_extension_index = deallocate (instance_extension_index);
+       instance_extension_array = deallocate (instance_extension_array);
+
+       print ("Enumerated /2instance extension properties/-.\n");
+
+       application_information.sType              = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+       application_information.pApplicationName   = application;
+       application_information.applicationVersion = VK_MAKE_VERSION (1, 0, 0);
+       application_information.pEngineName        = "xulkan";
+       application_information.engineVersion      = VK_MAKE_VERSION (1, 0, 0);
+       application_information.apiVersion         = VK_API_VERSION_1_0;
+
+       instance_information.sType                   = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+       instance_information.pApplicationInfo        = & application_information;
+       instance_information.enabledLayerCount       = default_instance_layer_count;
+       instance_information.ppEnabledLayerNames     = default_instance_layer_array;
+       instance_information.enabledExtensionCount   = default_instance_extension_count;
+       instance_information.ppEnabledExtensionNames = default_instance_extension_array;
+
+       vulkan_result (vkCreateInstance (& instance_information, null, & vulkan->instance));
+
+       print ("/c Created /2Vulkan instance/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_surface (vulkan_structure * vulkan) {
+       VkXcbSurfaceCreateInfoKHR surface_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       surface_information.sType      = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
+       surface_information.connection = vulkan->connection;
+       surface_information.window     = vulkan->window;
+
+       vulkan_result (vkCreateXcbSurfaceKHR (vulkan->instance, & surface_information, null, & vulkan->surface));
+
+       print ("/c Created /2Vulkan-XCB surface/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_device (vulkan_structure * vulkan) {
+       VkDeviceQueueCreateInfo          queues             = { 0 };
+       VkDeviceCreateInfo               device_information = { 0 };
+       VkPhysicalDeviceMemoryProperties memory_properties  = { 0 };
+
+       uint               queue_count           = 0;
+       uint               physical_device_count = 0;
+       VkPhysicalDevice * physical_device_array = null;
+       VkBool32         * support               = null;
+
+       const float queue_priorities [1] = { 1 };
+
+       const uint default_device_extension_count = 1;
+
+       const char * default_device_extension_array [VK_MAX_EXTENSION_NAME_SIZE] = {
+               VK_KHR_SWAPCHAIN_EXTENSION_NAME
+       };
+
+       vulkan->time = tick_tock ();
+
+       vulkan_result (vkEnumeratePhysicalDevices (vulkan->instance, & physical_device_count, null));
+
+       print ("Device count: /2%i/-\n", physical_device_count);
+
+       physical_device_array = allocate (physical_device_count * sizeof (VkPhysicalDevice));
+
+       vulkan_result (vkEnumeratePhysicalDevices (vulkan->instance, & physical_device_count, physical_device_array));
+
+       print ("Enumerated available physical devices.\n");
+
+       for (uint index = 0; index < physical_device_count; ++index) {
+               uint general = 0;
+               uint current = 0;
+
+               uint                    device_extension_count = 0;
+               uint                  * device_extension_index = null;
+               VkExtensionProperties * device_extension_array = null;
+
+               VkPhysicalDeviceProperties physical_device_properties = { 0 };
+               VkPhysicalDeviceFeatures   physical_device_features   = { 0 };
+
+               VkQueueFamilyProperties * queue_properties = null;
+
+               vkGetPhysicalDeviceProperties (physical_device_array [index], & physical_device_properties);
+               vkGetPhysicalDeviceFeatures   (physical_device_array [index], & physical_device_features);
+
+#define get_fucking_version(i) \
+       VK_VERSION_MAJOR(i),   \
+       VK_VERSION_MINOR(i),   \
+       VK_VERSION_PATCH(i)
+               print ("Physical device: /2%s/-\n",       physical_device_properties.deviceName);
+               print ("Device ID:       /2%i/-\n",       physical_device_properties.deviceID);
+               print ("API version:     /2%i.%i.%i/-\n", get_fucking_version (physical_device_properties.apiVersion));
+               print ("Driver version:  /2%i.%i.%i/-\n", get_fucking_version (physical_device_properties.driverVersion));
+#undef get_fucking_version
+
+               switch (physical_device_properties.deviceType) {
+                       case (VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU): print ("Device type:     /2Integrated GPU/-\n"); break;
+                       case (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU):   print ("Device type:     /2Discrete GPU/-\n");   break;
+                       case (VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU):    print ("Device type:     /2Virtual GPU/-\n");    break;
+                       case (VK_PHYSICAL_DEVICE_TYPE_CPU):            print ("Device type:     /2CPU/-\n");            break;
+                       default:                                       print ("Device type:     /2Other/-\n");          break;
+               }
+
+               switch (physical_device_properties.vendorID) {
+                       case (VK_VENDOR_ID_VIV):      print ("Vendor:          /2VIV/-\n");      break;
+                       case (VK_VENDOR_ID_VSI):      print ("Vendor:          /2VSI/-\n");      break;
+                       case (VK_VENDOR_ID_KAZAN):    print ("Vendor:          /2Kazan/-\n");    break;
+                       case (VK_VENDOR_ID_CODEPLAY): print ("Vendor:          /2Codeplay/-\n"); break;
+                       case (VK_VENDOR_ID_MESA):     print ("Vendor:          /2MESA/-\n");     break;
+                       case (VK_VENDOR_ID_POCL):     print ("Vendor:          /2POCL/-\n");     break;
+                       default:                      print ("Vendor:          /2Other/-\n");    break;
+               }
+
+               vulkan_result (vkEnumerateDeviceExtensionProperties (physical_device_array [index], null, & device_extension_count, null));
+
+               print ("Device extensions available: %i\n", device_extension_count);
+
+               device_extension_index = allocate (device_extension_count * sizeof (* device_extension_index));
+               device_extension_array = allocate (device_extension_count * sizeof (* device_extension_array));
+
+               vulkan_result (vkEnumerateDeviceExtensionProperties (physical_device_array [index], null, & device_extension_count,
+                                                                    device_extension_array));
+
+               for (current = 0; current < device_extension_count; ++current) {
+                       for (general = 0; general < default_device_extension_count; ++general) {
+                               if (string_compare (device_extension_array [current].extensionName, (char *) default_device_extension_array [general])) {
+                                       device_extension_index [current] = true;
+                               }
+                       }
+               }
+
+               for (current = 0; current < device_extension_count; ++current) {
+                       print ("\t[%t] %s\n", device_extension_index [current], device_extension_array [current].extensionName);
+               }
+
+               device_extension_index = deallocate (device_extension_index);
+               device_extension_array = deallocate (device_extension_array);
+
+               vkGetPhysicalDeviceQueueFamilyProperties (physical_device_array [index], & queue_count, null);
+
+               queue_properties = allocate (queue_count * sizeof (VkQueueFamilyProperties));
+
+               vkGetPhysicalDeviceQueueFamilyProperties (physical_device_array [index], & queue_count, queue_properties);
+
+               vulkan->queue_index = 0;
+
+               if ((physical_device_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
+               ||  (physical_device_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)) {
+                       vulkan->physical_device = physical_device_array [index];
+               }
+
+               queue_properties = deallocate (queue_properties);
+
+               print ("Enumerated device layer properties.\n");
+
+               print ("Enumerated device extension properties.\n");
+       }
+
+       vulkan->physical_device = physical_device_array [1]; /// THIS SHIT SUCKS.
+
+       VkPhysicalDeviceProperties selected_physical_device_properties = { 0 };
+
+       vkGetPhysicalDeviceProperties (vulkan->physical_device, & selected_physical_device_properties);
+
+       print ("/c Selecting physical device '/2%s/-'.\n", selected_physical_device_properties.deviceName);
+
+       physical_device_array = deallocate (physical_device_array);
+
+       queues.sType            = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+       queues.queueFamilyIndex = vulkan->queue_index;
+       queues.queueCount       = 1;
+       queues.pQueuePriorities = queue_priorities;
+
+       device_information.sType                   = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+       device_information.queueCreateInfoCount    = 1;
+       device_information.pQueueCreateInfos       = & queues;
+       device_information.enabledExtensionCount   = default_device_extension_count;
+       device_information.ppEnabledExtensionNames = default_device_extension_array;
+       device_information.pEnabledFeatures        = null;
+
+       vulkan_result (vkCreateDevice (vulkan->physical_device, & device_information, null, & vulkan->logical_device));
+
+       print ("/c Created Vulkan logical device.\n");
+
+       vkGetDeviceQueue (vulkan->logical_device, vulkan->queue_index, 0, & vulkan->queue);
+
+       vkGetPhysicalDeviceQueueFamilyProperties (vulkan->physical_device, & queue_count, null);
+
+       support = allocate (queue_count * sizeof (VkBool32));
+
+       for (uint index = 0; index < queue_count; ++index) {
+               vulkan_result (vkGetPhysicalDeviceSurfaceSupportKHR (vulkan->physical_device, index, vulkan->surface, & support [index]));
+       }
+
+       for (uint index = 0; (index != queue_count) && (! (vulkan->queue_index = support [index] ? (index++) : 0)); );
+
+       support = deallocate (support);
+
+       vkGetPhysicalDeviceMemoryProperties (vulkan->physical_device, & memory_properties);
+
+       print ("Found /2Vulkan physical device/- memory properties.\n");
+
+       for (uint index = 0; index < memory_properties.memoryTypeCount; ++index) {
+               print ("> %i\n", memory_properties.memoryTypes [index].propertyFlags);
+       }
+
+       print ("Found /2Vulkan surface support/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_choose_extent (vulkan_structure * vulkan) {
+       VkSurfaceCapabilitiesKHR capabilities = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       vulkan_result (vkGetPhysicalDeviceSurfaceCapabilitiesKHR (vulkan->physical_device, vulkan->surface, & capabilities));
+
+       vulkan->image_count = capabilities.minImageCount + 1;
+
+       vulkan->extent.width  = vulkan->width;
+       vulkan->extent.height = vulkan->height;
+
+       vulkan->extent.width  = (vulkan->extent.width  < capabilities.minImageExtent.width)  ? capabilities.minImageExtent.width  : vulkan->extent.width;
+       vulkan->extent.height = (vulkan->extent.height < capabilities.minImageExtent.height) ? capabilities.minImageExtent.height : vulkan->extent.height;
+
+       vulkan->extent.width  = (vulkan->extent.width  > capabilities.maxImageExtent.width)  ? capabilities.maxImageExtent.width  : vulkan->extent.width;
+       vulkan->extent.height = (vulkan->extent.height > capabilities.maxImageExtent.height) ? capabilities.maxImageExtent.height : vulkan->extent.height;
+
+       vulkan->transform       = capabilities.supportedTransforms     & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
+       vulkan->composite_alpha = capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+
+       print ("Found /2Vulkan-XCB surface capabilities/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_choose_format (vulkan_structure * vulkan) {
+       uint                 format_count = 0;
+       VkSurfaceFormatKHR * format_array = null;
+
+       vulkan->time = tick_tock ();
+
+       vulkan_result (vkGetPhysicalDeviceSurfaceFormatsKHR (vulkan->physical_device, vulkan->surface, & format_count, null));
+
+       format_array = allocate (format_count * sizeof (VkSurfaceFormatKHR));
+
+       vulkan_result (vkGetPhysicalDeviceSurfaceFormatsKHR (vulkan->physical_device, vulkan->surface, & format_count, format_array));
+
+       print ("Available surface format count: /2%i/-\n", format_count);
+
+       vulkan->format = VK_FORMAT_B8G8R8A8_UNORM;
+
+       format_array = deallocate (format_array);
+
+       print ("Choosing default /2Vulkan surface formats/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_choose_present_mode (vulkan_structure * vulkan) {
+       uint               present_mode_count = 0;
+       VkPresentModeKHR * present_mode_array = null;
+
+       vulkan->time = tick_tock ();
+
+       vulkan_result (vkGetPhysicalDeviceSurfacePresentModesKHR (vulkan->physical_device, vulkan->surface, & present_mode_count, null));
+
+       present_mode_array = allocate (present_mode_count * sizeof (VkPresentModeKHR));
+
+       vulkan_result (vkGetPhysicalDeviceSurfacePresentModesKHR (vulkan->physical_device, vulkan->surface, & present_mode_count,
+                                                                 present_mode_array));
+
+       vulkan->present_mode = VK_PRESENT_MODE_FIFO_KHR;
+
+       present_mode_array = deallocate (present_mode_array);
+
+       print ("Choosing FIFO /2Vulkan surface present mode/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_swapchain (vulkan_structure * vulkan) {
+       VkSwapchainCreateInfoKHR swapchain_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       swapchain_information.sType                 = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+       swapchain_information.surface               = vulkan->surface;
+       swapchain_information.minImageCount         = vulkan->image_count;
+       swapchain_information.imageFormat           = vulkan->format;
+       swapchain_information.imageColorSpace       = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
+       swapchain_information.imageExtent           = vulkan->extent;
+       swapchain_information.imageArrayLayers      = 1;
+       swapchain_information.imageUsage            = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+       swapchain_information.imageSharingMode      = VK_SHARING_MODE_EXCLUSIVE;
+       swapchain_information.queueFamilyIndexCount = 0;
+       swapchain_information.pQueueFamilyIndices   = null;
+       swapchain_information.preTransform          = vulkan->transform;
+       swapchain_information.compositeAlpha        = vulkan->composite_alpha;
+       swapchain_information.presentMode           = vulkan->present_mode;
+       swapchain_information.clipped               = VK_TRUE;
+       swapchain_information.oldSwapchain          = VK_NULL_HANDLE;
+
+       vulkan_result (vkCreateSwapchainKHR (vulkan->logical_device, & swapchain_information, null, & vulkan->swapchain));
+
+       print ("/c Created /2Vulkan swapchain/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_images (vulkan_structure * vulkan) {
+       uint temporary = vulkan->image_count;
+
+       vulkan->time = tick_tock ();
+
+       vulkan_result (vkGetSwapchainImagesKHR (vulkan->logical_device, vulkan->swapchain, & temporary, null));
+
+       vulkan->images = allocate (vulkan->image_count * sizeof (VkImage));
+
+       vulkan_result (vkGetSwapchainImagesKHR (vulkan->logical_device, vulkan->swapchain, & temporary, vulkan->images));
+
+       print ("/c Created /2Vulkan swapchain images/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_image_views (vulkan_structure * vulkan) {
+       VkComponentMapping      component_mapping       = { 0 };
+       VkImageSubresourceRange image_subresource_range = { 0 };
+       VkImageViewCreateInfo   image_view_information  = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       vulkan->image_views = allocate (vulkan->image_count * sizeof (VkImageView));
+
+       component_mapping.r = VK_COMPONENT_SWIZZLE_R;
+       component_mapping.g = VK_COMPONENT_SWIZZLE_G;
+       component_mapping.b = VK_COMPONENT_SWIZZLE_B;
+       component_mapping.a = VK_COMPONENT_SWIZZLE_A;
+
+       image_subresource_range.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+       image_subresource_range.baseMipLevel   = 0;
+       image_subresource_range.levelCount     = 1;
+       image_subresource_range.baseArrayLayer = 0;
+       image_subresource_range.layerCount     = 1;
+
+       image_view_information.sType            = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+       image_view_information.viewType         = VK_IMAGE_VIEW_TYPE_2D;
+       image_view_information.format           = vulkan->format;
+       image_view_information.components       = component_mapping;
+       image_view_information.subresourceRange = image_subresource_range;
+
+       for (uint index = 0; index < vulkan->image_count; ++index) {
+               image_view_information.image = vulkan->images [index];
+
+               vulkan_result (vkCreateImageView (vulkan->logical_device, & image_view_information, null, & vulkan->image_views [index]));
+       }
+
+       print ("/c Created /2Vulkan swapchain image views/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_semaphores (vulkan_structure * vulkan) {
+       VkSemaphoreCreateInfo semaphore_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       vulkan->semaphore_set_1 = allocate (vulkan->image_count * sizeof (VkSemaphore));
+       vulkan->semaphore_set_2 = allocate (vulkan->image_count * sizeof (VkSemaphore));
+
+       semaphore_information.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+
+       for (uint index = 0; index < vulkan->image_count; ++index) {
+               vulkan_result (vkCreateSemaphore (vulkan->logical_device, & semaphore_information, null, & vulkan->semaphore_set_1 [index]));
+               vulkan_result (vkCreateSemaphore (vulkan->logical_device, & semaphore_information, null, & vulkan->semaphore_set_2 [index]));
+       }
+
+       print ("/c Created /2Vulkan synchronization semaphores/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_fences (vulkan_structure * vulkan) {
+       uint index = 0;
+
+       VkFenceCreateInfo fence_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       vulkan->fence_set_1 = allocate (vulkan->image_count * sizeof (VkFence));
+
+       fence_information.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+       fence_information.flags = VK_FENCE_CREATE_SIGNALED_BIT;
+
+       for (index = 0; index < vulkan->image_count; ++index) {
+               vulkan_result (vkCreateFence (vulkan->logical_device, & fence_information, null, & vulkan->fence_set_1 [index]));
+       }
+
+       print ("/c Created /2Vulkan synchronization fences/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_render_pass (vulkan_structure * vulkan) {
+       VkAttachmentDescription attachment_description      = { 0 };
+       VkAttachmentReference   attachment_reference        = { 0 };
+       VkSubpassDescription    subpass_description         = { 0 };
+       VkSubpassDependency     subpass_dependencies    [2] = { { 0 } };
+       VkRenderPassCreateInfo  render_pass_information     = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       attachment_description.flags          = 0;
+       attachment_description.format         = vulkan->format;
+       attachment_description.samples        = VK_SAMPLE_COUNT_1_BIT;
+       attachment_description.loadOp         = VK_ATTACHMENT_LOAD_OP_CLEAR;
+       attachment_description.storeOp        = VK_ATTACHMENT_STORE_OP_STORE;
+       attachment_description.stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+       attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+       attachment_description.initialLayout  = VK_IMAGE_LAYOUT_UNDEFINED;
+       attachment_description.finalLayout    = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+
+       attachment_reference.attachment = 0;
+       attachment_reference.layout     = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+       subpass_description.flags                   = 0;
+       subpass_description.pipelineBindPoint       = VK_PIPELINE_BIND_POINT_GRAPHICS;
+       subpass_description.inputAttachmentCount    = 0;
+       subpass_description.pInputAttachments       = null;
+       subpass_description.colorAttachmentCount    = 1;
+       subpass_description.pColorAttachments       = & attachment_reference;
+       subpass_description.pResolveAttachments     = null;
+       subpass_description.pDepthStencilAttachment = null;
+       subpass_description.preserveAttachmentCount = 0;
+       subpass_description.pPreserveAttachments    = null;
+
+       subpass_dependencies [0].srcSubpass      = VK_SUBPASS_EXTERNAL;
+       subpass_dependencies [0].dstSubpass      = 0;
+       subpass_dependencies [0].srcStageMask    = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+       subpass_dependencies [0].dstStageMask    = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+       subpass_dependencies [0].srcAccessMask   = VK_ACCESS_MEMORY_READ_BIT;
+       subpass_dependencies [0].dstAccessMask   = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+       subpass_dependencies [0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
+       subpass_dependencies [1].srcSubpass      = 0;
+       subpass_dependencies [1].dstSubpass      = VK_SUBPASS_EXTERNAL;
+       subpass_dependencies [1].srcStageMask    = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+       subpass_dependencies [1].dstStageMask    = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+       subpass_dependencies [1].srcAccessMask   = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+       subpass_dependencies [1].dstAccessMask   = VK_ACCESS_MEMORY_READ_BIT;
+       subpass_dependencies [1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
+
+       render_pass_information.sType           = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+       render_pass_information.attachmentCount = 1;
+       render_pass_information.pAttachments    = & attachment_description;
+       render_pass_information.subpassCount    = 1;
+       render_pass_information.pSubpasses      = & subpass_description;
+       render_pass_information.dependencyCount = 2;
+       render_pass_information.pDependencies   = subpass_dependencies;
+
+       vulkan_result (vkCreateRenderPass (vulkan->logical_device, & render_pass_information, null, & vulkan->render_pass));
+
+       print ("/c Created /2Vulkan render pass/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_descriptor_set_layout (vulkan_structure * vulkan) {
+       VkDescriptorSetLayoutBinding    descriptor_set_layout_bindings    [2] = { { 0 } };
+       VkDescriptorSetLayoutCreateInfo descriptor_set_layout_information     = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       descriptor_set_layout_bindings [0].binding            = 0;
+       descriptor_set_layout_bindings [0].descriptorType     = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+       descriptor_set_layout_bindings [0].descriptorCount    = 1;
+       descriptor_set_layout_bindings [0].stageFlags         = VK_SHADER_STAGE_VERTEX_BIT;
+       descriptor_set_layout_bindings [0].pImmutableSamplers = null;
+       descriptor_set_layout_bindings [1].binding            = 1;
+       descriptor_set_layout_bindings [1].descriptorType     = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+       descriptor_set_layout_bindings [1].descriptorCount    = 1;
+       descriptor_set_layout_bindings [1].stageFlags         = VK_SHADER_STAGE_FRAGMENT_BIT;
+       descriptor_set_layout_bindings [1].pImmutableSamplers = null;
+
+       descriptor_set_layout_information.sType        = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+       descriptor_set_layout_information.bindingCount = 2;
+       descriptor_set_layout_information.pBindings    = descriptor_set_layout_bindings;
+
+       vulkan_result (vkCreateDescriptorSetLayout (vulkan->logical_device, & descriptor_set_layout_information, null,
+                                                   & vulkan->descriptor_set_layout));
+
+       print ("/c Created /2 Vulkan descriptor layout/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_vertex_shader (vulkan_structure * vulkan) {
+       const uint vertex_shader_code [] = {
+               0x07230203,     0x00010000,     0x000d000b,     0x00000028,     0x00000000,     0x00020011,     0x00000001,     0x0006000b,
+               0x00000001,     0x4c534c47,     0x6474732e,     0x3035342e,     0x00000000,     0x0003000e,     0x00000000,     0x00000001,
+               0x000b000f,     0x00000000,     0x00000004,     0x6e69616d,     0x00000000,     0x0000000d,     0x00000012,     0x00000021,
+               0x00000022,     0x00000024,     0x00000026,     0x00030003,     0x00000002,     0x000001c2,     0x000a0004,     0x475f4c47,
+               0x4c474f4f,     0x70635f45,     0x74735f70,     0x5f656c79,     0x656e696c,     0x7269645f,     0x69746365,     0x00006576,
+               0x00080004,     0x475f4c47,     0x4c474f4f,     0x6e695f45,     0x64756c63,     0x69645f65,     0x74636572,     0x00657669,
+               0x00040005,     0x00000004,     0x6e69616d,     0x00000000,     0x00060005,     0x0000000b,     0x505f6c67,     0x65567265,
+               0x78657472,     0x00000000,     0x00060006,     0x0000000b,     0x00000000,     0x505f6c67,     0x7469736f,     0x006e6f69,
+               0x00070006,     0x0000000b,     0x00000001,     0x505f6c67,     0x746e696f,     0x657a6953,     0x00000000,     0x00070006,
+               0x0000000b,     0x00000002,     0x435f6c67,     0x4470696c,     0x61747369,     0x0065636e,     0x00070006,     0x0000000b,
+               0x00000003,     0x435f6c67,     0x446c6c75,     0x61747369,     0x0065636e,     0x00030005,     0x0000000d,     0x00000000,
+               0x00030005,     0x00000012,     0x00797869,     0x00030005,     0x00000021,     0x0076756f,     0x00030005,     0x00000022,
+               0x00767569,     0x00030005,     0x00000024,     0x0000636f,     0x00030005,     0x00000026,     0x00006369,     0x00050048,
+               0x0000000b,     0x00000000,     0x0000000b,     0x00000000,     0x00050048,     0x0000000b,     0x00000001,     0x0000000b,
+               0x00000001,     0x00050048,     0x0000000b,     0x00000002,     0x0000000b,     0x00000003,     0x00050048,     0x0000000b,
+               0x00000003,     0x0000000b,     0x00000004,     0x00030047,     0x0000000b,     0x00000002,     0x00040047,     0x00000012,
+               0x0000001e,     0x00000000,     0x00040047,     0x00000021,     0x0000001e,     0x00000000,     0x00040047,     0x00000022,
+               0x0000001e,     0x00000001,     0x00040047,     0x00000024,     0x0000001e,     0x00000001,     0x00040047,     0x00000026,
+               0x0000001e,     0x00000002,     0x00020013,     0x00000002,     0x00030021,     0x00000003,     0x00000002,     0x00030016,
+               0x00000006,     0x00000020,     0x00040017,     0x00000007,     0x00000006,     0x00000004,     0x00040015,     0x00000008,
+               0x00000020,     0x00000000,     0x0004002b,     0x00000008,     0x00000009,     0x00000001,     0x0004001c,     0x0000000a,
+               0x00000006,     0x00000009,     0x0006001e,     0x0000000b,     0x00000007,     0x00000006,     0x0000000a,     0x0000000a,
+               0x00040020,     0x0000000c,     0x00000003,     0x0000000b,     0x0004003b,     0x0000000c,     0x0000000d,     0x00000003,
+               0x00040015,     0x0000000e,     0x00000020,     0x00000001,     0x0004002b,     0x0000000e,     0x0000000f,     0x00000000,
+               0x00040017,     0x00000010,     0x00000006,     0x00000002,     0x00040020,     0x00000011,     0x00000001,     0x00000010,
+               0x0004003b,     0x00000011,     0x00000012,     0x00000001,     0x0004002b,     0x00000008,     0x00000013,     0x00000000,
+               0x00040020,     0x00000014,     0x00000001,     0x00000006,     0x0004002b,     0x00000006,     0x00000017,     0x3f800000,
+               0x0004002b,     0x00000006,     0x0000001c,     0x00000000,     0x00040020,     0x0000001e,     0x00000003,     0x00000007,
+               0x00040020,     0x00000020,     0x00000003,     0x00000010,     0x0004003b,     0x00000020,     0x00000021,     0x00000003,
+               0x0004003b,     0x00000011,     0x00000022,     0x00000001,     0x0004003b,     0x0000001e,     0x00000024,     0x00000003,
+               0x00040020,     0x00000025,     0x00000001,     0x00000007,     0x0004003b,     0x00000025,     0x00000026,     0x00000001,
+               0x00050036,     0x00000002,     0x00000004,     0x00000000,     0x00000003,     0x000200f8,     0x00000005,     0x00050041,
+               0x00000014,     0x00000015,     0x00000012,     0x00000013,     0x0004003d,     0x00000006,     0x00000016,     0x00000015,
+               0x00050083,     0x00000006,     0x00000018,     0x00000016,     0x00000017,     0x00050041,     0x00000014,     0x00000019,
+               0x00000012,     0x00000009,     0x0004003d,     0x00000006,     0x0000001a,     0x00000019,     0x00050083,     0x00000006,
+               0x0000001b,     0x0000001a,     0x00000017,     0x00070050,     0x00000007,     0x0000001d,     0x00000018,     0x0000001b,
+               0x0000001c,     0x00000017,     0x00050041,     0x0000001e,     0x0000001f,     0x0000000d,     0x0000000f,     0x0003003e,
+               0x0000001f,     0x0000001d,     0x0004003d,     0x00000010,     0x00000023,     0x00000022,     0x0003003e,     0x00000021,
+               0x00000023,     0x0004003d,     0x00000007,     0x00000027,     0x00000026,     0x0003003e,     0x00000024,     0x00000027,
+               0x000100fd,     0x00010038
+       };
+
+       VkShaderModuleCreateInfo vertex_shader_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       vertex_shader_information.sType    = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+       vertex_shader_information.codeSize = sizeof (vertex_shader_code);
+       vertex_shader_information.pCode    = vertex_shader_code;
+
+       vulkan_result (vkCreateShaderModule (vulkan->logical_device, & vertex_shader_information, null, & vulkan->vertex_shader));
+
+       print ("/c Created /2Vulkan vertex shader module/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_fragment_shader (vulkan_structure * vulkan) {
+       const uint fragment_shader_code [] = {
+               0x07230203,     0x00010000,     0x000d000b,     0x00000018,     0x00000000,     0x00020011,     0x00000001,     0x0006000b,
+               0x00000001,     0x4c534c47,     0x6474732e,     0x3035342e,     0x00000000,     0x0003000e,     0x00000000,     0x00000001,
+               0x0008000f,     0x00000004,     0x00000004,     0x6e69616d,     0x00000000,     0x00000009,     0x00000011,     0x00000015,
+               0x00030010,     0x00000004,     0x00000007,     0x00030003,     0x00000002,     0x000001c2,     0x000a0004,     0x475f4c47,
+               0x4c474f4f,     0x70635f45,     0x74735f70,     0x5f656c79,     0x656e696c,     0x7269645f,     0x69746365,     0x00006576,
+               0x00080004,     0x475f4c47,     0x4c474f4f,     0x6e695f45,     0x64756c63,     0x69645f65,     0x74636572,     0x00657669,
+               0x00040005,     0x00000004,     0x6e69616d,     0x00000000,     0x00040005,     0x00000009,     0x69727073,     0x00006574,
+               0x00060005,     0x0000000d,     0x74786574,     0x5f657275,     0x706d6173,     0x0072656c,     0x00030005,     0x00000011,
+               0x00007675,     0x00030005,     0x00000015,     0x0000636f,     0x00040047,     0x00000009,     0x0000001e,     0x00000000,
+               0x00040047,     0x0000000d,     0x00000022,     0x00000000,     0x00040047,     0x0000000d,     0x00000021,     0x00000001,
+               0x00040047,     0x00000011,     0x0000001e,     0x00000000,     0x00040047,     0x00000015,     0x0000001e,     0x00000001,
+               0x00020013,     0x00000002,     0x00030021,     0x00000003,     0x00000002,     0x00030016,     0x00000006,     0x00000020,
+               0x00040017,     0x00000007,     0x00000006,     0x00000004,     0x00040020,     0x00000008,     0x00000003,     0x00000007,
+               0x0004003b,     0x00000008,     0x00000009,     0x00000003,     0x00090019,     0x0000000a,     0x00000006,     0x00000001,
+               0x00000000,     0x00000000,     0x00000000,     0x00000001,     0x00000000,     0x0003001b,     0x0000000b,     0x0000000a,
+               0x00040020,     0x0000000c,     0x00000000,     0x0000000b,     0x0004003b,     0x0000000c,     0x0000000d,     0x00000000,
+               0x00040017,     0x0000000f,     0x00000006,     0x00000002,     0x00040020,     0x00000010,     0x00000001,     0x0000000f,
+               0x0004003b,     0x00000010,     0x00000011,     0x00000001,     0x00040020,     0x00000014,     0x00000001,     0x00000007,
+               0x0004003b,     0x00000014,     0x00000015,     0x00000001,     0x00050036,     0x00000002,     0x00000004,     0x00000000,
+               0x00000003,     0x000200f8,     0x00000005,     0x0004003d,     0x0000000b,     0x0000000e,     0x0000000d,     0x0004003d,
+               0x0000000f,     0x00000012,     0x00000011,     0x00050057,     0x00000007,     0x00000013,     0x0000000e,     0x00000012,
+               0x0004003d,     0x00000007,     0x00000016,     0x00000015,     0x00050085,     0x00000007,     0x00000017,     0x00000013,
+               0x00000016,     0x0003003e,     0x00000009,     0x00000017,     0x000100fd,     0x00010038
+       };
+
+       VkShaderModuleCreateInfo fragment_shader_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       fragment_shader_information.sType    = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+       fragment_shader_information.codeSize = sizeof (fragment_shader_code);
+       fragment_shader_information.pCode    = fragment_shader_code;
+
+       vulkan_result (vkCreateShaderModule (vulkan->logical_device, & fragment_shader_information, null, & vulkan->fragment_shader));
+
+       print ("/c Created /2Vulkan fragment shader module/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_pipeline_layout (vulkan_structure * vulkan) {
+       VkPipelineLayoutCreateInfo pipeline_layout_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       pipeline_layout_information.sType                  = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+       pipeline_layout_information.setLayoutCount         = 1;
+       pipeline_layout_information.pSetLayouts            = & vulkan->descriptor_set_layout;
+
+       vulkan_result (vkCreatePipelineLayout (vulkan->logical_device, & pipeline_layout_information, VK_NULL_HANDLE, & vulkan->pipeline_layout));
+
+       print ("/c Created /2Vulkan graphics pipeline layout/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_pipeline (vulkan_structure * vulkan) {
+       VkPipelineShaderStageCreateInfo        pipeline_shader_stage_information         [2] = { { 0 } };
+       VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly_state_information     = { 0 };
+       VkVertexInputBindingDescription        vertex_input_binding_description          [1] = { { 0 } };
+       VkVertexInputAttributeDescription      vertex_input_attribute_description        [4] = { { 0 } };
+       VkPipelineVertexInputStateCreateInfo   pipeline_vertex_input_state_information       = { 0 };
+       VkViewport                             viewport                                      = { 0 };
+       VkOffset2D                             scissor_offset                                = { 0 };
+       VkExtent2D                             scissor_extent                                = { 0 };
+       VkRect2D                               scissor                                       = { 0 };
+       VkPipelineViewportStateCreateInfo      pipeline_viewport_state_information           = { 0 };
+       VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_information      = { 0 };
+       VkPipelineMultisampleStateCreateInfo   pipeline_multisample_state_information        = { 0 };
+       VkPipelineColorBlendAttachmentState    pipeline_colour_blend_attachment_state        = { 0 };
+       VkPipelineColorBlendStateCreateInfo    pipeline_colour_blend_state_information       = { 0 };
+       VkGraphicsPipelineCreateInfo           pipeline_information                          = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       pipeline_shader_stage_information [0].sType               = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+       pipeline_shader_stage_information [0].stage               = VK_SHADER_STAGE_VERTEX_BIT;
+       pipeline_shader_stage_information [0].module              = vulkan->vertex_shader;
+       pipeline_shader_stage_information [0].pName               = "main";
+       pipeline_shader_stage_information [0].pSpecializationInfo = null;
+       pipeline_shader_stage_information [1].sType               = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+       pipeline_shader_stage_information [1].stage               = VK_SHADER_STAGE_FRAGMENT_BIT;
+       pipeline_shader_stage_information [1].module              = vulkan->fragment_shader;
+       pipeline_shader_stage_information [1].pName               = "main";
+       pipeline_shader_stage_information [1].pSpecializationInfo = null;
+
+       pipeline_input_assembly_state_information.sType                  = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+       pipeline_input_assembly_state_information.topology               = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+       pipeline_input_assembly_state_information.primitiveRestartEnable = VK_FALSE;
+
+       vertex_input_binding_description [0].binding   = 0;
+       vertex_input_binding_description [0].stride    = 32;
+       vertex_input_binding_description [0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
+
+       vertex_input_attribute_description [0].binding  = vertex_input_binding_description [0].binding;
+       vertex_input_attribute_description [0].location = 0;
+       vertex_input_attribute_description [0].format   = VK_FORMAT_R32G32_SFLOAT;
+       vertex_input_attribute_description [0].offset   = 0;
+       vertex_input_attribute_description [1].binding  = vertex_input_binding_description [0].binding;
+       vertex_input_attribute_description [1].location = 1;
+       vertex_input_attribute_description [1].format   = VK_FORMAT_R32G32_SFLOAT;
+       vertex_input_attribute_description [1].offset   = 8;
+       vertex_input_attribute_description [2].binding  = vertex_input_binding_description [0].binding;
+       vertex_input_attribute_description [2].location = 2;
+       vertex_input_attribute_description [2].format   = VK_FORMAT_R32G32B32A32_SFLOAT;
+       vertex_input_attribute_description [2].offset   = 16;
+
+       pipeline_vertex_input_state_information.sType                           = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+       pipeline_vertex_input_state_information.vertexBindingDescriptionCount   = 1;
+       pipeline_vertex_input_state_information.pVertexBindingDescriptions      = vertex_input_binding_description;
+       pipeline_vertex_input_state_information.vertexAttributeDescriptionCount = 3;
+       pipeline_vertex_input_state_information.pVertexAttributeDescriptions    = vertex_input_attribute_description;
+
+       viewport.x        = 0;
+       viewport.y        = 0;
+       viewport.width    = vulkan->width;
+       viewport.height   = vulkan->height;
+       viewport.minDepth = 0;
+       viewport.maxDepth = 1;
+
+       scissor_offset.x = 0;
+       scissor_offset.y = 0;
+
+       scissor_extent.width  = vulkan->width;
+       scissor_extent.height = vulkan->height;
+
+       scissor.offset = scissor_offset;
+       scissor.extent = scissor_extent;
+
+       pipeline_viewport_state_information.sType         = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+       pipeline_viewport_state_information.viewportCount = 1;
+       pipeline_viewport_state_information.pViewports    = & viewport;
+       pipeline_viewport_state_information.scissorCount  = 1;
+       pipeline_viewport_state_information.pScissors     = & scissor;
+
+       pipeline_rasterization_state_information.sType                   = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+       pipeline_rasterization_state_information.depthClampEnable        = VK_FALSE;
+       pipeline_rasterization_state_information.rasterizerDiscardEnable = VK_FALSE;
+       pipeline_rasterization_state_information.polygonMode             = VK_POLYGON_MODE_FILL;
+       pipeline_rasterization_state_information.cullMode                = VK_CULL_MODE_BACK_BIT;
+       pipeline_rasterization_state_information.frontFace               = VK_FRONT_FACE_CLOCKWISE;
+       pipeline_rasterization_state_information.depthBiasEnable         = VK_FALSE;
+       pipeline_rasterization_state_information.depthBiasConstantFactor = 0;
+       pipeline_rasterization_state_information.depthBiasClamp          = 0;
+       pipeline_rasterization_state_information.depthBiasSlopeFactor    = 0;
+       pipeline_rasterization_state_information.lineWidth               = 1;
+
+       pipeline_multisample_state_information.sType                 = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+       pipeline_multisample_state_information.rasterizationSamples  = VK_SAMPLE_COUNT_1_BIT;
+       pipeline_multisample_state_information.sampleShadingEnable   = VK_FALSE;
+       pipeline_multisample_state_information.minSampleShading      = 1;
+       pipeline_multisample_state_information.pSampleMask           = null;
+       pipeline_multisample_state_information.alphaToCoverageEnable = VK_FALSE;
+       pipeline_multisample_state_information.alphaToOneEnable      = VK_FALSE;
+
+       pipeline_colour_blend_attachment_state.blendEnable         = VK_TRUE;
+       pipeline_colour_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
+       pipeline_colour_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+       pipeline_colour_blend_attachment_state.colorBlendOp        = VK_BLEND_OP_ADD;
+       pipeline_colour_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
+       pipeline_colour_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
+       pipeline_colour_blend_attachment_state.alphaBlendOp        = VK_BLEND_OP_ADD;
+       pipeline_colour_blend_attachment_state.colorWriteMask      = VK_COLOR_COMPONENT_R_BIT
+                                                                  | VK_COLOR_COMPONENT_G_BIT
+                                                                  | VK_COLOR_COMPONENT_B_BIT
+                                                                  | VK_COLOR_COMPONENT_A_BIT;
+
+       pipeline_colour_blend_state_information.sType           = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+       pipeline_colour_blend_state_information.logicOpEnable   = VK_FALSE;
+       pipeline_colour_blend_state_information.logicOp         = VK_LOGIC_OP_COPY;
+       pipeline_colour_blend_state_information.attachmentCount = 1;
+       pipeline_colour_blend_state_information.pAttachments    = & pipeline_colour_blend_attachment_state;
+
+       pipeline_information.sType               = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+       pipeline_information.flags               = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
+       pipeline_information.stageCount          = 2;
+       pipeline_information.pStages             = pipeline_shader_stage_information;
+       pipeline_information.pVertexInputState   = & pipeline_vertex_input_state_information;
+       pipeline_information.pInputAssemblyState = & pipeline_input_assembly_state_information;
+       pipeline_information.pTessellationState  = null;
+       pipeline_information.pViewportState      = & pipeline_viewport_state_information;
+       pipeline_information.pRasterizationState = & pipeline_rasterization_state_information;
+       pipeline_information.pMultisampleState   = & pipeline_multisample_state_information;
+       pipeline_information.pDepthStencilState  = null;
+       pipeline_information.pColorBlendState    = & pipeline_colour_blend_state_information;
+       pipeline_information.pDynamicState       = null;
+       pipeline_information.layout              = vulkan->pipeline_layout;
+       pipeline_information.renderPass          = vulkan->render_pass;
+       pipeline_information.subpass             = 0;
+       pipeline_information.basePipelineHandle  = VK_NULL_HANDLE;
+       pipeline_information.basePipelineIndex   = -1;
+
+       vulkan_result (vkCreateGraphicsPipelines (vulkan->logical_device, VK_NULL_HANDLE, 1, & pipeline_information, null, & vulkan->pipeline));
+
+       print ("/c Created /2Vulkan graphics pipeline/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_framebuffers (vulkan_structure * vulkan) {
+       VkFramebufferCreateInfo framebuffer_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       vulkan->framebuffers = allocate (vulkan->image_count * sizeof (VkFramebuffer));
+
+       framebuffer_information.sType           = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+       framebuffer_information.renderPass      = vulkan->render_pass;
+       framebuffer_information.attachmentCount = 1;
+       framebuffer_information.width           = vulkan->extent.width;
+       framebuffer_information.height          = vulkan->extent.height;
+       framebuffer_information.layers          = 1;
+
+       for (uint index = 0; index < vulkan->image_count; ++index) {
+               framebuffer_information.pAttachments = & vulkan->image_views [index];
+
+               vulkan_result (vkCreateFramebuffer (vulkan->logical_device, & framebuffer_information, null, & vulkan->framebuffers [index]));
+       }
+
+       print ("/c Created /2Vulkan framebuffers/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_command_pool (vulkan_structure * vulkan) {
+       VkCommandPoolCreateInfo command_pool_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       command_pool_information.sType            = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+       command_pool_information.flags            = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+       command_pool_information.queueFamilyIndex = vulkan->queue_index;
+
+       vulkan_result (vkCreateCommandPool (vulkan->logical_device, & command_pool_information, null, & vulkan->command_pool));
+
+       print ("/c Created /2Vulkan command pool/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_command_buffers (vulkan_structure * vulkan) {
+       VkCommandBufferAllocateInfo command_buffer_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       vulkan->command_buffers = allocate (vulkan->image_count * sizeof (VkCommandBuffer));
+
+       command_buffer_information.sType              = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+       command_buffer_information.commandPool        = vulkan->command_pool;
+       command_buffer_information.level              = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+       command_buffer_information.commandBufferCount = vulkan->image_count;
+
+       vulkan_result (vkAllocateCommandBuffers (vulkan->logical_device, & command_buffer_information, vulkan->command_buffers));
+
+       print ("/c Allocated /2Vulkan command buffers/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_vertex_buffer (vulkan_structure * vulkan) {
+       VkBuffer         transfer_buffer = VK_NULL_HANDLE;
+       VkDeviceMemory   transfer_memory = VK_NULL_HANDLE;
+       void           * transfer_void   = null;
+
+       VkBufferCopy copy_information = { 0 };
+/*
+       vulkan->time = tick_tock ();
+*/
+       vulkan->vertex_size = vulkan->vertex_count * sizeof (* vulkan->vertex_data);
+
+       vulkan_create_buffer (vulkan, & transfer_buffer, & transfer_memory, vulkan->vertex_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
+
+       vulkan_result (vkMapMemory (vulkan->logical_device, transfer_memory, 0, vulkan->vertex_size, 0, & transfer_void));
+
+       memory_copy (transfer_void, vulkan->vertex_data, vulkan->vertex_size);
+
+       vulkan_create_buffer (vulkan, & vulkan->vertex_buffer, & vulkan->vertex_memory, vulkan->vertex_size,
+                             VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+
+       vulkan_begin_command_buffer (vulkan);
+
+       copy_information.srcOffset = 0;
+       copy_information.dstOffset = 0;
+       copy_information.size      = vulkan->vertex_size;
+
+       vkCmdCopyBuffer (vulkan->transfer_buffer, transfer_buffer, vulkan->vertex_buffer, 1, & copy_information);
+
+       vulkan_end_command_buffer (vulkan);
+
+       vkDestroyBuffer (vulkan->logical_device, transfer_buffer, null);
+       vkFreeMemory    (vulkan->logical_device, transfer_memory, null);
+
+       /*print ("/c Created /2Vulkan vertex buffer/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);*/
+}
+
+static void vulkan_create_index_buffer (vulkan_structure * vulkan) {
+       VkBuffer         transfer_buffer = VK_NULL_HANDLE;
+       VkDeviceMemory   transfer_memory = VK_NULL_HANDLE;
+       void           * transfer_void   = null;
+
+       VkBufferCopy copy_information = { 0 };
+/*
+       vulkan->time = tick_tock ();
+*/
+       vulkan->index_size = vulkan->index_count * sizeof (* vulkan->index_data);
+
+       vulkan_create_buffer (vulkan, & transfer_buffer, & transfer_memory, vulkan->index_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
+
+       vulkan_result (vkMapMemory (vulkan->logical_device, transfer_memory, 0, vulkan->index_size, 0, & transfer_void));
+
+       memory_copy (transfer_void, vulkan->index_data, vulkan->index_size);
+
+       vulkan_create_buffer (vulkan, & vulkan->index_buffer, & vulkan->index_memory, vulkan->index_size,
+                             VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+
+       vulkan_begin_command_buffer (vulkan);
+
+       copy_information.srcOffset = 0;
+       copy_information.dstOffset = 0;
+       copy_information.size      = vulkan->index_size;
+
+       vkCmdCopyBuffer (vulkan->transfer_buffer, transfer_buffer, vulkan->index_buffer, 1, & copy_information);
+
+       vulkan_end_command_buffer (vulkan);
+
+       vkDestroyBuffer (vulkan->logical_device, transfer_buffer, null);
+       vkFreeMemory    (vulkan->logical_device, transfer_memory, null);
+/*
+       print ("/c Created /2Vulkan index buffer/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);*/
+}
+
+static void vulkan_create_image_buffer (vulkan_structure * vulkan) {
+       VkBuffer         transfer_buffer = VK_NULL_HANDLE;
+       VkDeviceMemory   transfer_memory = VK_NULL_HANDLE;
+       void           * transfer_void   = null;
+
+       VkExtent3D               image_extent                  = { 0 };
+       VkImageCreateInfo        image_information             = { 0 };
+       VkMemoryRequirements     memory_requirements           = { 0 };
+       VkMemoryAllocateInfo     memory_allocation_information = { 0 };
+       VkImageSubresourceLayers region_subresource_layers     = { 0 };
+       VkOffset3D               region_offset                 = { 0 };
+       VkExtent3D               region_extent                 = { 0 };
+       VkBufferImageCopy        region_copying_information    = { 0 };
+       VkComponentMapping       component_mapping             = { 0 };
+       VkImageSubresourceRange  image_subresource_range       = { 0 };
+       VkImageViewCreateInfo    image_view_information        = { 0 };
+       VkImageMemoryBarrier     image_memory_barrier          = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       vulkan_create_buffer (vulkan, & transfer_buffer, & transfer_memory, vulkan->layout_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
+
+       vulkan_result (vkMapMemory (vulkan->logical_device, transfer_memory, 0, vulkan->layout_size, 0, & transfer_void));
+
+       memory_copy (transfer_void, vulkan->layout_data, vulkan->layout_size);
+
+       image_extent.width  = vulkan->layout_width;
+       image_extent.height = vulkan->layout_height;
+       image_extent.depth  = 1;
+
+       image_information.sType         = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+       image_information.imageType     = VK_IMAGE_TYPE_2D;
+       image_information.format        = vulkan->format;
+       image_information.extent        = image_extent;
+       image_information.mipLevels     = 1;
+       image_information.arrayLayers   = 1;
+       image_information.samples       = VK_SAMPLE_COUNT_1_BIT;
+       image_information.tiling        = VK_IMAGE_TILING_OPTIMAL;
+       image_information.usage         = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
+       image_information.sharingMode   = VK_SHARING_MODE_EXCLUSIVE;
+       image_information.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+       image_subresource_range.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+       image_subresource_range.baseMipLevel   = 0;
+       image_subresource_range.levelCount     = 1;
+       image_subresource_range.baseArrayLayer = 0;
+       image_subresource_range.layerCount     = 1;
+
+       vulkan_result (vkCreateImage (vulkan->logical_device, & image_information, null, & vulkan->layout_image));
+
+       vkGetImageMemoryRequirements (vulkan->logical_device, vulkan->layout_image, & memory_requirements);
+
+       memory_allocation_information.sType           = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+       memory_allocation_information.allocationSize  = memory_requirements.size;
+       memory_allocation_information.memoryTypeIndex = vulkan_choose_memory_property (vulkan, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
+       vulkan_result (vkAllocateMemory (vulkan->logical_device, & memory_allocation_information, null, & vulkan->layout_memory));
+
+       vulkan_result (vkBindImageMemory (vulkan->logical_device, vulkan->layout_image, vulkan->layout_memory, 0));
+
+       vulkan_begin_command_buffer (vulkan);
+
+       image_memory_barrier.sType               = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+       image_memory_barrier.pNext               = null;
+       image_memory_barrier.srcAccessMask       = 0;
+       image_memory_barrier.dstAccessMask       = VK_ACCESS_TRANSFER_WRITE_BIT;
+       image_memory_barrier.oldLayout           = VK_IMAGE_LAYOUT_UNDEFINED;
+       image_memory_barrier.newLayout           = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+       image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+       image_memory_barrier.image               = vulkan->layout_image;
+       image_memory_barrier.subresourceRange    = image_subresource_range;
+
+       vkCmdPipelineBarrier (vulkan->transfer_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, null, 0, null,
+                             1, & image_memory_barrier);
+
+       vulkan_end_command_buffer (vulkan);
+
+       vulkan_begin_command_buffer (vulkan);
+
+       region_subresource_layers.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+       region_subresource_layers.mipLevel       = 0;
+       region_subresource_layers.baseArrayLayer = 0;
+       region_subresource_layers.layerCount     = 1;
+
+       region_offset.x = 0;
+       region_offset.y = 0;
+       region_offset.z = 0;
+
+       region_extent.width  = vulkan->layout_width;
+       region_extent.height = vulkan->layout_height;
+       region_extent.depth  = 1;
+
+       region_copying_information.bufferOffset      = 0;
+       region_copying_information.bufferRowLength   = 0;
+       region_copying_information.bufferImageHeight = 0;
+       region_copying_information.imageSubresource  = region_subresource_layers;
+       region_copying_information.imageOffset       = region_offset;
+       region_copying_information.imageExtent       = region_extent;
+
+       vkCmdCopyBufferToImage (vulkan->transfer_buffer, transfer_buffer, vulkan->layout_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
+                               & region_copying_information);
+
+       vulkan_end_command_buffer (vulkan);
+
+       vulkan_begin_command_buffer (vulkan);
+
+       image_memory_barrier.sType               = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+       image_memory_barrier.pNext               = null;
+       image_memory_barrier.srcAccessMask       = VK_ACCESS_TRANSFER_WRITE_BIT;
+       image_memory_barrier.dstAccessMask       = VK_ACCESS_SHADER_READ_BIT;
+       image_memory_barrier.oldLayout           = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       image_memory_barrier.newLayout           = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+       image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+       image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+       image_memory_barrier.image               = vulkan->layout_image;
+       image_memory_barrier.subresourceRange    = image_subresource_range;
+
+       vkCmdPipelineBarrier (vulkan->transfer_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, null, 0,
+                             null, 1, & image_memory_barrier);
+
+       vulkan_end_command_buffer (vulkan);
+
+       component_mapping.r = VK_COMPONENT_SWIZZLE_R;
+       component_mapping.g = VK_COMPONENT_SWIZZLE_G;
+       component_mapping.b = VK_COMPONENT_SWIZZLE_B;
+       component_mapping.a = VK_COMPONENT_SWIZZLE_A;
+
+       image_view_information.sType            = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+       image_view_information.viewType         = VK_IMAGE_VIEW_TYPE_2D;
+       image_view_information.format           = vulkan->format;
+       image_view_information.components       = component_mapping;
+       image_view_information.subresourceRange = image_subresource_range;
+       image_view_information.image            = vulkan->layout_image;
+
+       vulkan_result (vkCreateImageView (vulkan->logical_device, & image_view_information, null, & vulkan->layout_image_view));
+
+       vkDestroyBuffer (vulkan->logical_device, transfer_buffer, null);
+       vkFreeMemory    (vulkan->logical_device, transfer_memory, null);
+
+       print ("/c Created /2Vulkan image layout buffer/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_sampler (vulkan_structure * vulkan) {
+       VkSamplerCreateInfo sampler_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       sampler_information.sType                   = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+       sampler_information.magFilter               = VK_FILTER_NEAREST;
+       sampler_information.minFilter               = VK_FILTER_NEAREST;
+       sampler_information.mipmapMode              = VK_SAMPLER_MIPMAP_MODE_NEAREST;
+       sampler_information.addressModeU            = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+       sampler_information.addressModeV            = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+       sampler_information.addressModeW            = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+       sampler_information.mipLodBias              = 0;
+       sampler_information.anisotropyEnable        = VK_FALSE;
+       sampler_information.maxAnisotropy           = 1;
+       sampler_information.compareEnable           = VK_FALSE;
+       sampler_information.compareOp               = VK_COMPARE_OP_ALWAYS;
+       sampler_information.minLod                  = 0;
+       sampler_information.maxLod                  = 0;
+       sampler_information.borderColor             = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
+       sampler_information.unnormalizedCoordinates = VK_FALSE;
+
+       vulkan_result (vkCreateSampler (vulkan->logical_device, & sampler_information, null, & vulkan->sampler));
+
+       print ("/c Created /2Vulkan sampler/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_descriptor_pool (vulkan_structure * vulkan) {
+       VkDescriptorPoolSize       descriptor_pool_sizes       [2] = { { 0 } };
+       VkDescriptorPoolCreateInfo descriptor_pool_information     = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       descriptor_pool_sizes[0].type            = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+       descriptor_pool_sizes[0].descriptorCount = vulkan->image_count;
+       descriptor_pool_sizes[1].type            = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+       descriptor_pool_sizes[1].descriptorCount = vulkan->image_count;
+
+       descriptor_pool_information.sType         = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+       descriptor_pool_information.flags         = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
+       descriptor_pool_information.maxSets       = vulkan->image_count;
+       descriptor_pool_information.poolSizeCount = 2;
+       descriptor_pool_information.pPoolSizes    = descriptor_pool_sizes;
+
+       vulkan_result (vkCreateDescriptorPool (vulkan->logical_device, & descriptor_pool_information, null, & vulkan->descriptor_pool));
+
+       print ("/c Created /2Vulkan descriptor pool/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_create_descriptor_sets (vulkan_structure * vulkan) {
+       VkDescriptorSetAllocateInfo descriptor_set_allocation_information = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       vulkan->descriptor_set_layouts = allocate (vulkan->image_count * sizeof (VkDescriptorSetLayout));
+
+       for (uint index = 0; index < vulkan->image_count; ++index) {
+               vulkan->descriptor_set_layouts [index] = vulkan->descriptor_set_layout;
+       }
+
+       descriptor_set_allocation_information.sType              = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+       descriptor_set_allocation_information.descriptorPool     = vulkan->descriptor_pool;
+       descriptor_set_allocation_information.descriptorSetCount = vulkan->image_count;
+       descriptor_set_allocation_information.pSetLayouts        = vulkan->descriptor_set_layouts;
+
+       vulkan->descriptor_sets = allocate (vulkan->image_count * sizeof (VkDescriptorSet));
+
+       vulkan_result (vkAllocateDescriptorSets (vulkan->logical_device, & descriptor_set_allocation_information, vulkan->descriptor_sets));
+
+       print ("/c Allocated /2Vulkan descriptor sets/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_record_descriptor_sets (vulkan_structure * vulkan) {
+       VkDescriptorBufferInfo descriptor_buffer_information = { 0 };
+       VkDescriptorImageInfo  descriptor_image_information  = { 0 };
+       VkWriteDescriptorSet   write_descriptor_set          = { 0 };
+
+       vulkan->time = tick_tock ();
+
+       descriptor_image_information.sampler     = vulkan->sampler;
+       descriptor_image_information.imageView   = vulkan->layout_image_view;
+       descriptor_image_information.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+       write_descriptor_set.sType           = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+       write_descriptor_set.dstBinding      = 1;
+       write_descriptor_set.dstArrayElement = 0;
+       write_descriptor_set.descriptorCount = 1;
+       write_descriptor_set.descriptorType  = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+       write_descriptor_set.pImageInfo      = & descriptor_image_information;
+       write_descriptor_set.pBufferInfo     = null;
+
+       for (uint index = 0; index < vulkan->image_count; ++index) {
+               write_descriptor_set.dstSet = vulkan->descriptor_sets [index];
+
+               vkUpdateDescriptorSets (vulkan->logical_device, 1, & write_descriptor_set, 0, null);
+       }
+
+       print ("/c Recorded /2Vulkan descriptor sets/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);
+}
+
+static void vulkan_record_command_buffers (vulkan_structure * vulkan, int clear_colour, int frame) {
+       uint index = 0;
+
+       VkCommandBufferBeginInfo command_buffer_begin_information = { 0 };
+       //~VkImageSubresourceRange  image_subresource_range          = { 0 };
+       VkClearValue             clear_value                      = { 0 };
+       VkOffset2D               render_area_offset               = { 0 };
+       VkExtent2D               render_area_extent               = { 0 };
+       VkRect2D                 render_area                      = { 0 };
+       VkRenderPassBeginInfo    render_pass_begin_information    = { 0 };
+       VkDeviceSize             vertex_offset                    = 0;
+
+       VkClearColorValue clear_colour_value = { {
+               (float) ((clear_colour & 0xff000000) >> 24) / 255,
+               (float) ((clear_colour & 0x00ff0000) >> 16) / 255,
+               (float) ((clear_colour & 0x0000ff00) >>  8) / 255,
+               (float) ((clear_colour & 0x000000ff) >>  0) / 255
+       } };
+
+       (void) frame;
+/*
+       vulkan->time = tick_tock ();
+*/
+       command_buffer_begin_information.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+       command_buffer_begin_information.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
+
+       //~image_subresource_range.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+       //~image_subresource_range.baseMipLevel   = 0;
+       //~image_subresource_range.levelCount     = 1;
+       //~image_subresource_range.baseArrayLayer = 0;
+       //~image_subresource_range.layerCount     = 1;
+
+       clear_value.color = clear_colour_value;
+
+       render_area_offset.x = 0;
+       render_area_offset.y = 0;
+
+       render_area_extent.width  = vulkan->extent.width;
+       render_area_extent.height = vulkan->extent.height;
+
+       render_area.offset = render_area_offset;
+       render_area.extent = render_area_extent;
+
+       render_pass_begin_information.sType           = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+       render_pass_begin_information.pNext           = null;
+       render_pass_begin_information.renderPass      = vulkan->render_pass;
+       render_pass_begin_information.renderArea      = render_area;
+       render_pass_begin_information.clearValueCount = 1;
+       render_pass_begin_information.pClearValues    = & clear_value;
+
+       for (index = 0; index < vulkan->image_count; ++index) {
+               render_pass_begin_information.framebuffer = vulkan->framebuffers [index];
+
+               vulkan_result (vkBeginCommandBuffer (vulkan->command_buffers [index], & command_buffer_begin_information));
+
+               vkCmdBeginRenderPass (vulkan->command_buffers [index], & render_pass_begin_information, VK_SUBPASS_CONTENTS_INLINE);
+
+               vkCmdBindPipeline (vulkan->command_buffers [index], VK_PIPELINE_BIND_POINT_GRAPHICS, vulkan->pipeline);
+
+               vkCmdBindVertexBuffers (vulkan->command_buffers [index], 0, 1, & vulkan->vertex_buffer, & vertex_offset);
+
+               vkCmdBindIndexBuffer (vulkan->command_buffers [index], vulkan->index_buffer, 0, VK_INDEX_TYPE_UINT32);
+
+               vkCmdBindDescriptorSets (vulkan->command_buffers [index], VK_PIPELINE_BIND_POINT_GRAPHICS, vulkan->pipeline_layout, 0, 1,
+                                        vulkan->descriptor_sets, 0, null);
+
+               vkCmdDrawIndexed (vulkan->command_buffers [index], vulkan->index_count, 1, 0, 0, 0);
+
+               vkCmdEndRenderPass (vulkan->command_buffers [index]);
+
+               vulkan_result (vkEndCommandBuffer (vulkan->command_buffers [index]));
+       }
+/*
+       render_pass_begin_information.framebuffer = vulkan_framebuffers [frame];
+
+       vulkan_result (vkBeginCommandBuffer (vulkan_command_buffers [frame], & command_buffer_begin_information));
+
+       vkCmdBeginRenderPass (vulkan_command_buffers [frame], & render_pass_begin_information, VK_SUBPASS_CONTENTS_INLINE);
+
+       vkCmdBindPipeline (vulkan_command_buffers [frame], VK_PIPELINE_BIND_POINT_GRAPHICS, vulkan_pipeline);
+
+       vkCmdBindVertexBuffers (vulkan_command_buffers [frame], 0, 1, & vulkan_vertex_buffer, & vertex_offset);
+
+       vkCmdBindIndexBuffer (vulkan_command_buffers [frame], vulkan_index_buffer, 0, VK_INDEX_TYPE_UINT32);
+
+       vkCmdBindDescriptorSets (vulkan_command_buffers [frame], VK_PIPELINE_BIND_POINT_GRAPHICS, vulkan_pipeline_layout, 0, 1,
+                                vulkan_descriptor_sets, 0, null);
+
+       vkCmdDrawIndexed (vulkan_command_buffers [frame], vulkan_index_count, 1, 0, 0, 0);
+
+       vkCmdEndRenderPass (vulkan_command_buffers [frame]);
+
+       vulkan_result (vkEndCommandBuffer (vulkan_command_buffers [frame]));
+*/
+       vulkan_result (vkQueueWaitIdle  (vulkan->queue));
+       vulkan_result (vkDeviceWaitIdle (vulkan->logical_device));
+
+       /*print ("/c Recorded /2Vulkan command buffers/-.\n");
+       print ("/c Time approximation: /6%i/-\n", tick_tock () - vulkan->time);*/
+}
+
+static uint vulkan_import_sprite (vulkan_structure * vulkan, uint * data, uint width, uint height) {
+       fatal_failure (vulkan->active == true, "vulkan_import_sprite: Failed to import sprite, engine was already configured.");
+       fatal_failure (data           == null, "vulkan_import_sprite: Failed to import sprite, data is null pointer.");
+       fatal_failure (width          <= 0,    "vulkan_import_sprite: Failed to import sprite, width is equal or below zero.");
+       fatal_failure (height         <= 0,    "vulkan_import_sprite: Failed to import sprite, height is equal or below zero.");
+
+       ++vulkan->sprite_count;
+
+       vulkan->sprite_data   = reallocate (vulkan->sprite_data,   vulkan->sprite_count * sizeof (* vulkan->sprite_data));
+       vulkan->sprite_width  = reallocate (vulkan->sprite_width,  vulkan->sprite_count * sizeof (* vulkan->sprite_width));
+       vulkan->sprite_height = reallocate (vulkan->sprite_height, vulkan->sprite_count * sizeof (* vulkan->sprite_height));
+       vulkan->sprite_u      = reallocate (vulkan->sprite_u,      vulkan->sprite_count * sizeof (* vulkan->sprite_u));
+       vulkan->sprite_v      = reallocate (vulkan->sprite_v,      vulkan->sprite_count * sizeof (* vulkan->sprite_v));
+
+       vulkan->sprite_data   [vulkan->sprite_count - 1] = data;
+       vulkan->sprite_width  [vulkan->sprite_count - 1] = width;
+       vulkan->sprite_height [vulkan->sprite_count - 1] = height;
+       vulkan->sprite_u      [vulkan->sprite_count - 1] = 0;
+       vulkan->sprite_v      [vulkan->sprite_count - 1] = 0;
+
+       return (vulkan->sprite_count - 1);
+}
+
+static uint vulkan_import_font (vulkan_structure * vulkan, uint * data, uint image_width, uint image_height, char begin, char end, uint empty) {
+       uint pointer = 0;
+       char index   = 0;
+       uint width   = 0;
+       uint height  = 0;
+       uint x       = 0;
+       uint y       = 0;
+
+       uint * buffer = null;
+
+       ++vulkan->font_count;
+
+       vulkan->font_index  = reallocate (vulkan->font_index,  vulkan->font_count * sizeof (* vulkan->font_index));
+       vulkan->font_width  = reallocate (vulkan->font_width,  vulkan->font_count * sizeof (* vulkan->font_width));
+       vulkan->font_height = reallocate (vulkan->font_height, vulkan->font_count * sizeof (* vulkan->font_height));
+       vulkan->font_begin  = reallocate (vulkan->font_begin,  vulkan->font_count * sizeof (* vulkan->font_begin));
+       vulkan->font_end    = reallocate (vulkan->font_end,    vulkan->font_count * sizeof (* vulkan->font_end));
+
+       vulkan->font_begin [vulkan->font_count - 1] = begin;
+       vulkan->font_end   [vulkan->font_count - 1] = end;
+
+       vulkan->font_index  [vulkan->font_count - 1] = allocate ((end - begin + 1) * sizeof (* * vulkan->font_index));
+       vulkan->font_width  [vulkan->font_count - 1] = allocate ((end - begin + 1) * sizeof (* * vulkan->font_width));
+       vulkan->font_height [vulkan->font_count - 1] = allocate ((end - begin + 1) * sizeof (* * vulkan->font_height));
+
+       for (index = begin; index <= end; ++index) {
+               for (          ; data [pointer]                        == empty; ++pointer);
+               for (width  = 0; data [pointer + width]                != empty; ++width);
+               for (height = 0; data [pointer + height * image_width] != empty; ++height);
+
+               buffer = allocate (width * height * sizeof (* buffer));
+
+               for (y = 0; y < height; ++y) {
+                       for (x = 0; x < width; ++x) {
+                               buffer [y * width + x] = data [pointer + (y * image_width) + x];
+                       }
+               }
+
+               vulkan->font_index  [vulkan->font_count - 1] [index - begin] = vulkan_import_sprite (vulkan, buffer, width, height);
+               vulkan->font_width  [vulkan->font_count - 1] [index - begin] = width;
+               vulkan->font_height [vulkan->font_count - 1] [index - begin] = height;
+
+               pointer += width;
+
+               for (; data [pointer] == empty; ++pointer);
+
+               if (pointer % image_width == 2) {
+                       pointer += height * image_width;
+               }
+       }
+
+       return (vulkan->font_count - 1);
+}
+
+static void vulkan_bundle_layout (vulkan_structure * vulkan) {
+       uint * order = null;
+
+       vulkan->layout_size = vulkan->layout_width * vulkan->layout_height * (uint) sizeof (* vulkan->layout_data);
+
+       vulkan->layout_data = allocate (vulkan->layout_size);
+
+       order = allocate (vulkan->sprite_count * sizeof (* order));
+
+       for (uint index = 0; index < vulkan->sprite_count; ++index) {
+               order [index] = index;
+       }
+
+       for (uint index = 0; index < vulkan->sprite_count; ++index) {
+               for (uint subindex = 0; subindex < vulkan->sprite_count; ++subindex) {
+                       if (vulkan->sprite_height [order [index]] < vulkan->sprite_height [order [subindex]]) {
+                               int temporary = order [index];
+
+                               order [index]    = order [subindex];
+                               order [subindex] = temporary;
+                       }
+               }
+       }
+
+       for (uint index = 0; index < vulkan->sprite_count; ++index) {
+               uint x = 0;
+               uint y = 0;
+               uint u = 0;
+               uint v = 0;
+
+
+               if (u + vulkan->sprite_width [order [index]] >= vulkan->layout_width) {
+                       u *= 0;
+                       v += vulkan->sprite_height [order [index]];
+               }
+
+               vulkan->sprite_u [order [index]] = (float) u / (float) vulkan->layout_width;
+               vulkan->sprite_v [order [index]] = (float) v / (float) vulkan->layout_height;
+
+               for (uint y = 0; y < vulkan->sprite_height [order [index]]; ++y) {
+                       for (uint x = 0; x < vulkan->sprite_width [order [index]]; ++x) {
+                               uint destination = (v + y) * vulkan->layout_width + (u + x);
+                               uint source      = y * vulkan->sprite_width [order [index]] + x;
+
+                               vulkan->layout_data [destination] = vulkan->sprite_data [order [index]] [source];
+                       }
+               }
+
+               u += vulkan->sprite_width [order [index]];
+
+               vulkan->sprite_data [order [index]] = deallocate (vulkan->sprite_data [order [index]]);
+       }
+
+       vulkan->sprite_data = deallocate (vulkan->sprite_data);
+       order               = deallocate (order);
+}
+
+static void vulkan_configure (vulkan_structure * vulkan, int width, int height, const char * application) {
+       int index = 0;
+
+       uint * dumb_buffer = null;
+
+       if (vulkan->active == true) {
+               return;
+       }
+
+       vulkan->width  = width;
+       vulkan->height = height;
+
+       vulkan->pixel_width  = (float) 2 / (float) width;
+       vulkan->pixel_height = (float) 2 / (float) height;
+
+       dumb_buffer = allocate (256 * sizeof (* dumb_buffer));
+
+       for (index = 0; index < 256; ++index) {
+               dumb_buffer [index] = ~0;
+       }
+
+       vulkan_import_sprite (vulkan, dumb_buffer, 16, 16);
+
+       vulkan_bundle_layout (vulkan);
+
+       vulkan->vertex_data = allocate (vulkan->vertex_limit * sizeof (* vulkan->vertex_data));
+       vulkan->index_data  = allocate (vulkan->index_limit  * sizeof (* vulkan->index_data));
+
+       vulkan_create_window   (vulkan, application);
+       vulkan_create_instance (vulkan, application);
+       print ("/c Variable : width               = %i\n", vulkan->width);
+       print ("/c Variable : height              = %i\n", vulkan->height);
+       print ("/c Variable : sprite_count        = %i\n", vulkan->sprite_count);
+       print ("/c Variable : font_count          = %i\n", vulkan->font_count);
+       print ("/c Variable : gameplay_framerate  = %i\n", vulkan->gameplay_framerate);
+       print ("/c Variable : animation_framerate = %i\n", vulkan->animation_framerate);
+       print ("/c Variable : vertex_limit        = %i\n", vulkan->vertex_limit);
+       print ("/c Variable : index_limit         = %i\n", vulkan->index_limit);
+       print ("/c Variable : layout_size         = %i\n", vulkan->layout_size);
+       print ("/c Variable : layout_width        = %i\n", vulkan->layout_width);
+       print ("/c Variable : layout_height       = %i\n", vulkan->layout_height);
+
+       vulkan_create_surface               (vulkan);
+       vulkan_create_device                (vulkan);
+       vulkan_choose_extent                (vulkan);
+       vulkan_choose_format                (vulkan);
+       vulkan_choose_present_mode          (vulkan);
+       vulkan_create_swapchain             (vulkan);
+       vulkan_create_images                (vulkan);
+       vulkan_create_image_views           (vulkan);
+       vulkan_create_semaphores            (vulkan);
+       vulkan_create_fences                (vulkan);
+       vulkan_create_render_pass           (vulkan);
+       vulkan_create_descriptor_set_layout (vulkan);
+       vulkan_create_vertex_shader         (vulkan);
+       vulkan_create_fragment_shader       (vulkan);
+       vulkan_create_pipeline_layout       (vulkan);
+       vulkan_create_pipeline              (vulkan);
+       vulkan_create_framebuffers          (vulkan);
+       vulkan_create_command_pool          (vulkan);
+       vulkan_create_command_buffers       (vulkan);
+       vulkan_create_image_buffer          (vulkan);
+       vulkan_create_sampler               (vulkan);
+       vulkan_create_descriptor_pool       (vulkan);
+       vulkan_create_descriptor_sets       (vulkan);
+       vulkan_record_descriptor_sets       (vulkan);
+
+       vulkan->active = true;
+}
+/*
+static void vulkan_reconfigure (void) {
+       int index;
+
+       vulkan_result (vkQueueWaitIdle  (vulkan_queue));
+       vulkan_result (vkDeviceWaitIdle (vulkan_logical_device));
+
+       for (index = 0; index < vulkan_image_count; ++index) {
+               vkDestroyFramebuffer (vulkan_logical_device, vulkan_framebuffers [index], null);
+       }
+
+       vulkan_framebuffers = deallocate (vulkan_framebuffers);
+
+       for (index = 0; index < vulkan_image_count; ++index) {
+               vkDestroyImageView (vulkan_logical_device, vulkan_image_views [index], null);
+       }
+
+       vulkan_image_views = deallocate (vulkan_image_views);
+
+       vkDestroySwapchainKHR (vulkan_logical_device, vulkan_swapchain, null);
+
+       vulkan_images = deallocate (vulkan_images);
+
+       vulkan_choose_extent       ();
+       vulkan_choose_format       ();
+       vulkan_choose_present_mode ();
+       vulkan_create_swapchain    ();
+       vulkan_create_images       ();
+       vulkan_create_image_views  ();
+       vulkan_create_framebuffers ();
+
+       vulkan_result (vkQueueWaitIdle  (vulkan_queue));
+       vulkan_result (vkDeviceWaitIdle (vulkan_logical_device));
+
+       vulkan_reconfigure_active = false;
+}
+*/
+static void vulkan_render_core (vulkan_structure * vulkan, int sprite, int x, int y, int u, int v, int width, int height,
+                                float scale_x, float scale_y, int flip_x, int flip_y,
+                                int colour_0, uint colour_1, uint colour_2, uint colour_3) {
+       float screen_x = x * vulkan->pixel_width;
+       float screen_y = y * vulkan->pixel_height;
+
+       float unwrap_x = vulkan->sprite_u [sprite] + (float) u / vulkan->layout_width;
+       float unwrap_y = vulkan->sprite_v [sprite] + (float) v / vulkan->layout_height;
+
+       float screen_width  = (float) width  * vulkan->pixel_width  * scale_x;
+       float screen_height = (float) height * vulkan->pixel_height * scale_y;
+
+       float unwrap_width  = (float) width  / vulkan->layout_width;
+       float unwrap_height = (float) height / vulkan->layout_height;
+
+       fatal_failure (vulkan->vertex_count + 32 >= vulkan->vertex_limit, "Reached vertex limit.");
+       fatal_failure (vulkan->index_count  +  6 >= vulkan->index_limit,  "Reached index limit.");
+
+       vulkan->vertex_data [vulkan->vertex_count +  0] = screen_x;
+       vulkan->vertex_data [vulkan->vertex_count +  1] = screen_y;
+       vulkan->vertex_data [vulkan->vertex_count +  2] = unwrap_x + unwrap_width  * (flip_y != 0);
+       vulkan->vertex_data [vulkan->vertex_count +  3] = unwrap_y + unwrap_height * (flip_x != 0);
+       vulkan->vertex_data [vulkan->vertex_count +  4] = (float) ((colour_0 >> 24) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count +  5] = (float) ((colour_0 >> 16) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count +  6] = (float) ((colour_0 >>  8) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count +  7] = (float) ((colour_0 >>  0) & 0xff) / 255;
+
+       vulkan->vertex_data [vulkan->vertex_count +  8] = screen_x + screen_width;
+       vulkan->vertex_data [vulkan->vertex_count +  9] = screen_y;
+       vulkan->vertex_data [vulkan->vertex_count + 10] = unwrap_x + unwrap_width  * (flip_y == 0);
+       vulkan->vertex_data [vulkan->vertex_count + 11] = unwrap_y + unwrap_height * (flip_x != 0);
+       vulkan->vertex_data [vulkan->vertex_count + 12] = (float) ((colour_1 >> 24) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count + 13] = (float) ((colour_1 >> 16) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count + 14] = (float) ((colour_1 >>  8) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count + 15] = (float) ((colour_1 >>  0) & 0xff) / 255;
+
+       vulkan->vertex_data [vulkan->vertex_count + 16] = screen_x;
+       vulkan->vertex_data [vulkan->vertex_count + 17] = screen_y + screen_height;
+       vulkan->vertex_data [vulkan->vertex_count + 18] = unwrap_x + unwrap_width  * (flip_y != 0);
+       vulkan->vertex_data [vulkan->vertex_count + 19] = unwrap_y + unwrap_height * (flip_x == 0);
+       vulkan->vertex_data [vulkan->vertex_count + 20] = (float) ((colour_2 >> 24) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count + 21] = (float) ((colour_2 >> 16) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count + 22] = (float) ((colour_2 >>  8) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count + 23] = (float) ((colour_2 >>  0) & 0xff) / 255;
+
+       vulkan->vertex_data [vulkan->vertex_count + 24] = screen_x + screen_width;
+       vulkan->vertex_data [vulkan->vertex_count + 25] = screen_y + screen_height;
+       vulkan->vertex_data [vulkan->vertex_count + 26] = unwrap_x + unwrap_width  * (flip_y == 0);
+       vulkan->vertex_data [vulkan->vertex_count + 27] = unwrap_y + unwrap_height * (flip_x == 0);
+       vulkan->vertex_data [vulkan->vertex_count + 28] = (float) ((colour_3 >> 24) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count + 29] = (float) ((colour_3 >> 16) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count + 30] = (float) ((colour_3 >>  8) & 0xff) / 255;
+       vulkan->vertex_data [vulkan->vertex_count + 31] = (float) ((colour_3 >>  0) & 0xff) / 255;
+
+       vulkan->index_data [vulkan->index_count + 0] = (vulkan->vertex_count >> 3) + 0;
+       vulkan->index_data [vulkan->index_count + 1] = (vulkan->vertex_count >> 3) + 1;
+       vulkan->index_data [vulkan->index_count + 2] = (vulkan->vertex_count >> 3) + 2;
+       vulkan->index_data [vulkan->index_count + 3] = (vulkan->vertex_count >> 3) + 1;
+       vulkan->index_data [vulkan->index_count + 4] = (vulkan->vertex_count >> 3) + 3;
+       vulkan->index_data [vulkan->index_count + 5] = (vulkan->vertex_count >> 3) + 2;
+
+       vulkan->vertex_count += 32;
+       vulkan->index_count  += 6;
+}
+
+static void vulkan_render_sprite (vulkan_structure * vulkan, int sprite, int x, int y, uint colour) {
+       vulkan_render_core (vulkan, sprite, x, y, 0, 0, vulkan->sprite_width [sprite], vulkan->sprite_height [sprite], 1.0, 1.0, 0, 0, colour, colour, colour,colour);
+}
+
+static void vulkan_render_sprite_scale (vulkan_structure * vulkan, int sprite, int x, int y, float scale, uint colour) {
+       vulkan_render_core (vulkan, sprite, x, y, 0, 0, vulkan->sprite_width [sprite], vulkan->sprite_height [sprite], scale, scale, 0, 0, colour, colour, colour,colour);
+}
+
+static void vulkan_render_sprite_crop (vulkan_structure * vulkan, int sprite, int x, int y, int u, int v, int width, int height, uint colour) {
+       vulkan_render_core (vulkan, sprite, x, y, u, v, width, height, 1.0, 1.0, 0, 0, colour, colour, colour, colour);
+}
+
+static void vulkan_render_rectangle (vulkan_structure * vulkan, int x, int y, int width, int height, uint colour) {
+       vulkan_render_core (vulkan, vulkan->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16, (float) height / 16, 0, 0, colour, colour, colour, colour);
+}
+
+static void vulkan_render_rectangle_gradient_v (vulkan_structure * vulkan, int x, int y, int width, int height, uint colour_up, uint colour_down) {
+       vulkan_render_core (vulkan, vulkan->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16, (float) height / 16, 0, 0, colour_up, colour_up, colour_down, colour_down);
+}
+
+static void vulkan_render_rectangle_gradient_h (vulkan_structure * vulkan, int x, int y, int width, int height, uint colour_left, uint colour_right) {
+       vulkan_render_core (vulkan, vulkan->sprite_count - 1, x, y, 0, 0, 16, 16, (float) width / 16, (float) height / 16, 0, 0, colour_left, colour_right, colour_left, colour_right);
+}
+
+static int vulkan_string_width (vulkan_structure * vulkan, const char * string, int font, float scale) {
+       int length = 0;
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               int character = vulkan->font_index [font] [string [index] - vulkan->font_begin [font]];
+/*
+               if (string [index] == '\t') {
+                       length += 8 * vulkan->sprite_width [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]];
+                       continue;
+               }
+
+               if (string [index] == '\n') {
+                       continue;
+               }
+*/
+               length += vulkan->sprite_width [character] * scale;
+       }
+
+       return (length);
+}
+
+static void vulkan_render_string (vulkan_structure * vulkan, const char * string, int font, int x, int y, uint colour) {
+       int offset = x;
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               int character = vulkan->font_index [font] [string [index] - vulkan->font_begin [font]];
+
+               if (string [index] == '\t') {
+                       x += 8 * vulkan->sprite_width [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]];
+                       continue;
+               }
+
+               if (string [index] == '\n') {
+                       x  = offset;
+                       y += vulkan->sprite_height [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]];
+                       continue;
+               }
+
+               vulkan_render_sprite (vulkan, character, x, y, colour);
+
+               x += vulkan->sprite_width [character];
+       }
+}
+
+static void vulkan_render_string_scale (vulkan_structure * vulkan, const char * string, int font, int x, int y, float scale, uint colour) {
+       int offset = x;
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               int character = vulkan->font_index [font] [string [index] - vulkan->font_begin [font]];
+
+               if (string [index] == '\t') {
+                       x += 8 * vulkan->sprite_width [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]];
+                       continue;
+               }
+
+               if (string [index] == '\n') {
+                       x  = offset;
+                       y += vulkan->sprite_height [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]];
+                       continue;
+               }
+
+               vulkan_render_core (vulkan, character, x, y, 0, 0, vulkan->sprite_width [character], vulkan->sprite_height [character], scale, scale,
+                                   0, 0, colour, colour, colour, colour);
+
+               x += vulkan->sprite_width [character];
+       }
+}
+
+static void vulkan_render_string_offset (vulkan_structure * vulkan, const char * string, uint length, uint font, uint offset, int * x, int * y, uint colour) {
+       for (uint index = 0; (string [index] != '\0') && (index < length); ++index) {
+               uint character = vulkan->font_index [font] [string [index] - vulkan->font_begin [font]];
+
+               if (string [index] == '\t') {
+                       * x += 8 * vulkan->sprite_width [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]];
+                       continue;
+               }
+
+               if (string [index] == '\n') {
+                       * x  = offset;
+                       * y += vulkan->sprite_height [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]];
+                       continue;
+               }
+
+               vulkan_render_sprite (vulkan, character, * x, * y, colour);
+
+               * x += vulkan->sprite_width [character];
+       }
+}
+
+static void vulkan_render_string_gradient_v (vulkan_structure * vulkan, const char * string, int font, int x, int y, float scale, uint colour_up, uint colour_down) {
+       int offset = x;
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               uint character = vulkan->font_index [font] [string [index] - vulkan->font_begin [font]];
+
+               if (string [index] == '\t') {
+                       x += 8 * vulkan->sprite_width [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]] * scale;
+                       continue;
+               }
+
+               if (string [index] == '\n') {
+                       x  = offset;
+                       y += vulkan->sprite_height [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]] * scale;
+                       continue;
+               }
+
+               vulkan_render_core (vulkan, character, x, y, 0, 0, vulkan->sprite_width [character], vulkan->sprite_height [character], scale, scale,
+                                   0, 0, colour_up, colour_up, colour_down, colour_down);
+
+               x += vulkan->sprite_width [character] * scale;
+       }
+}
+
+static void vulkan_render_string_gradient_h (vulkan_structure * vulkan, const char * string, int font, int x, int y, float scale, uint colour_left, uint colour_right) {
+       int offset = x;
+
+       for (uint index = 0; string [index] != '\0'; ++index) {
+               uint character = vulkan->font_index [font] [string [index] - vulkan->font_begin [font]];
+
+               if (string [index] == '\t') {
+                       x += 8 * vulkan->sprite_width [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]] * scale;
+                       continue;
+               }
+
+               if (string [index] == '\n') {
+                       x  = offset;
+                       y += vulkan->sprite_height [vulkan->font_index [font] [' ' - vulkan->font_begin [font]]] * scale;
+                       continue;
+               }
+
+               vulkan_render_core (vulkan, character, x, y, 0, 0, vulkan->sprite_width [character], vulkan->sprite_height [character], scale, scale,
+                                   0, 0, colour_left, colour_right, colour_left, colour_right);
+
+               x += vulkan->sprite_width [character] * scale;
+       }
+}
+
+static void vulkan_handle_events (vulkan_structure * vulkan) {
+       static const int signal_code [signal_count] = {
+               0,
+               38,     56,     54,     40,     26,     41,     42,     43,     31,     44,     45,     46,     58,     57,     32,     33,
+               24,     27,     39,     28,     30,     55,     25,     53,     29,     52,     19,     10,     11,     12,     13,     14,
+               15,     16,     17,     18,      9,     23,     36,     36,     61,     51,     47,     49,     65,     22,     60,     59,
+               48,     66,     20,     21,     34,     35,     37,     105,    50,     62,     64,     108,    67,     68,     69,     70,
+               71,     72,     73,     74,     75,     76,     95,     96,     111,    116,    113,    114,    77,     127,    118,    110,
+               112,   119,    115,    117,     86,     82,     63,     106,    104,    91,     90,     87,     88,     89,     83,     84,
+               85, 79, 80, 81
+       };
+
+       int index, key_code;
+
+       xcb_generic_event_t * generic_event;
+
+       /*generic_event = xcb_wait_for_event (vulkan_connection);*/
+       generic_event = xcb_poll_for_event (vulkan->connection);
+
+       if (generic_event == null) {
+               return;
+       }
+
+       switch (generic_event->response_type & 127) {
+               case (XCB_EXPOSE): {
+                       xcb_flush (vulkan->connection);
+               } break;
+               /*case (XCB_CONFIGURE_NOTIFY): {
+                       const xcb_configure_notify_event_t * reconfigure = (const xcb_configure_notify_event_t *) generic_event;
+                       if ((reconfigure->width != vulkan->width) || (reconfigure->height != vulkan->height)) {
+                               vulkan->width  = reconfigure->width;
+                               vulkan->height = reconfigure->height;
+                               if ((vulkan->width > 0) && (vulkan->height > 0)) {
+                                       vulkan->reconfigure_active = true;
+                                       vulkan->reconfigure ();
+                               }
+                       }
+               } break;*/
+               case (XCB_BUTTON_PRESS): {
+                       vulkan->cursor   = (int) ((xcb_button_press_event_t *) generic_event)->detail;
+                       vulkan->cursor_x = (int) ((xcb_button_press_event_t *) generic_event)->event_x;
+                       vulkan->cursor_y = (int) ((xcb_button_press_event_t *) generic_event)->event_y;
+               } break;
+               case (XCB_BUTTON_RELEASE): {
+                       vulkan->cursor   = cursor_none;
+                       vulkan->cursor_x = (int) ((xcb_button_release_event_t *) generic_event)->event_x;
+                       vulkan->cursor_y = (int) ((xcb_button_release_event_t *) generic_event)->event_y;
+               } break;
+               case (XCB_KEY_PRESS): {
+                       key_code = (int) ((xcb_key_press_event_t *) generic_event)->detail;
+                       for (index = 0; index < signal_count; ++index) {
+                               if (key_code == signal_code [index]) {
+                                       vulkan->signal [index] = true;
+                                       break;
+                               }
+                       }
+               } break;
+               case (XCB_KEY_RELEASE): {
+                       key_code = (int) ((xcb_key_release_event_t *) generic_event)->detail;
+                       for (index = 0; index < signal_count; ++index) {
+                               if (key_code == signal_code [index]) {
+                                       vulkan->signal [index] = false;
+                                       break;
+                               }
+                       }
+               } break;
+               /*case (XCB_MOTION_NOTIFY): {
+                       vulkan->cursor_x = (int) ((xcb_motion_notify_event_t *) generic_event)->event_x;
+                       vulkan->cursor_y = (int) ((xcb_motion_notify_event_t *) generic_event)->event_y;
+               } break;*/
+               default: {
+               } break;
+       }
+
+       generic_event = deallocate (generic_event);
+}
+
+static void vulkan_synchronize (vulkan_structure * vulkan, uint clear_colour) {
+       uint index = 0;
+       uint frame = 0;
+
+       VkResult result = VK_SUCCESS;
+
+       void * ubo_void = null;
+
+       const VkPipelineStageFlags wait_stages [1] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT} ;
+
+       VkSubmitInfo     submit_information  = { 0 };
+       VkPresentInfoKHR present_information = { 0 };
+
+       VkSwapchainKHR * swapchain_pointer = & vulkan->swapchain;
+
+       struct timespec frame_begin = { 0 };
+       struct timespec frame_end   = { 0 };
+
+       clock_gettime (CLOCK_REALTIME, & frame_begin);
+
+       vulkan_handle_events (vulkan);
+
+       if ((vulkan->active == false) || (vulkan->reconfigure_active == true)) {
+               return;
+       }
+
+       if (vulkan->signal [signal_q] == true) {
+               vulkan->active = false;
+       }
+
+       vulkan_render_core (vulkan, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+       vulkan_create_vertex_buffer (vulkan);
+       vulkan_create_index_buffer  (vulkan);
+
+       vulkan_record_command_buffers (vulkan, clear_colour, frame);
+
+       vulkan_result (vkWaitForFences (vulkan->logical_device, 1, & vulkan->fence_set_1 [vulkan->frame], VK_TRUE, ~0));
+
+       vulkan_result (vkAcquireNextImageKHR (vulkan->logical_device, vulkan->swapchain, ~0, vulkan->semaphore_set_1 [vulkan->frame],
+                                             VK_NULL_HANDLE, & frame));
+/*
+       result = vkAcquireNextImageKHR (vulkan->logical_device, vulkan->swapchain, ~0, vulkan->semaphore_set_1 [vulkan->frame],
+                                       VK_NULL_HANDLE, & frame);
+
+       print ("vkAcquireNextImageKHR : /5%i/-\n", result);
+
+       if (result == VK_ERROR_OUT_OF_DATE_KHR) {
+               vulkan->reconfigure_active = true;
+               return;
+       }
+*/
+       vulkan_result (vkResetFences (vulkan->logical_device, 1, & vulkan->fence_set_1 [vulkan->frame]));
+
+       submit_information.sType                = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+       submit_information.waitSemaphoreCount   = 1;
+       submit_information.pWaitSemaphores      = & vulkan->semaphore_set_1 [vulkan->frame];
+       submit_information.pWaitDstStageMask    = wait_stages;
+       submit_information.commandBufferCount   = 1;
+       submit_information.pCommandBuffers      = & vulkan->command_buffers [vulkan->frame];
+       //~submit_information.pCommandBuffers      = & vulkan->command_buffers [frame];
+       submit_information.signalSemaphoreCount = 1;
+       submit_information.pSignalSemaphores    = & vulkan->semaphore_set_2 [vulkan->frame];
+
+       vulkan_result (vkQueueSubmit (vulkan->queue, 1, & submit_information, vulkan->fence_set_1 [vulkan->frame]));
+
+       present_information.sType              = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
+       present_information.waitSemaphoreCount = 1;
+       present_information.pWaitSemaphores    = & vulkan->semaphore_set_2 [vulkan->frame];
+       present_information.swapchainCount     = 1;
+       present_information.pSwapchains        = swapchain_pointer;
+       present_information.pImageIndices      = & frame;
+
+       vulkan_result (vkQueuePresentKHR (vulkan->queue, & present_information));
+/*
+       result = vkQueuePresentKHR (vulkan->queue, & present_information);
+
+       print ("vkQueuePresentKHR : /5%i/-\n", result);
+
+       if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) {
+               vulkan->reconfigure_active = true;
+               return;
+       }
+*/
+       vulkan->frame = (vulkan->frame + 1) % vulkan->image_count;
+
+       vulkan_result (vkQueueWaitIdle  (vulkan->queue));
+       vulkan_result (vkDeviceWaitIdle (vulkan->logical_device));
+
+       vkDestroyBuffer (vulkan->logical_device, vulkan->index_buffer,  null);
+       vkFreeMemory    (vulkan->logical_device, vulkan->index_memory,  null);
+       vkDestroyBuffer (vulkan->logical_device, vulkan->vertex_buffer, null);
+       vkFreeMemory    (vulkan->logical_device, vulkan->vertex_memory, null);
+
+       vulkan->vertex_count = 0;
+       vulkan->index_count  = 0;
+
+       vulkan_result (vkQueueWaitIdle  (vulkan->queue));
+       vulkan_result (vkDeviceWaitIdle (vulkan->logical_device));
+
+       clock_gettime (CLOCK_REALTIME, & frame_end);
+
+       if (vulkan->gameplay_time % (vulkan->gameplay_framerate / 10) == 0) {
+               vulkan->frame_time_in_ns = (frame_end.tv_sec - frame_begin.tv_sec) * 1000000000 + frame_end.tv_nsec - frame_begin.tv_nsec;
+
+               vulkan->framerate = (int) (1000000000 / vulkan->frame_time_in_ns);
+       }
+
+       if (vulkan->framerate > vulkan->gameplay_framerate) {
+               struct timespec wait = { 0, 0 };
+
+               wait.tv_nsec = 1000000000 / vulkan->gameplay_framerate - vulkan->frame_time_in_ns;
+
+               while (nanosleep (& wait, null) == -1) continue;
+       }
+
+       ++vulkan->global_time;
+
+       vulkan->global_time    = vulkan->global_time % (vulkan->gameplay_framerate * vulkan->animation_framerate);
+       vulkan->gameplay_time  = vulkan->global_time % (vulkan->gameplay_framerate);
+       vulkan->animation_time = vulkan->global_time / (vulkan->gameplay_framerate / vulkan->animation_framerate);
+}
diff --git a/xungeon.h b/xungeon.h
new file mode 100755 (executable)
index 0000000..b88cf7a
--- /dev/null
+++ b/xungeon.h
@@ -0,0 +1,271 @@
+// __  ___   _ _ __   __ _  ___  ___  _ __
+// \ \/ / | | | '_ \ / _` |/ _ \/ _ \| '_ \
+//  >  <| |_| | | | | (_| |  __/ (_) | | | |
+// /_/\_\\__,_|_| |_|\__, |\___|\___/|_| |_|
+//                   |___/
+//
+// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+//
+// xolatile@chud.cyou - xungeon - Small library for defining dungeon crawler gameplay information.
+//
+// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+//
+// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+//~typedef struct {
+       //~char * name;
+//~} * _definition;
+
+typedef struct {
+       char * name;        // Name string copy.
+       uint   temperature; // ;
+       uint   humidity;    // ;
+} * dungeon_biome_definition;
+
+typedef struct {
+       char * name;  // Name string copy.
+       uint   biome; // Index in biome array.
+       bool   clip;  // Can entities move through?
+} * dungeon_landmark_definition;
+
+typedef struct {
+       char * name; // Name string copy.
+} * dungeon_expertise_definition;
+
+typedef struct {
+       char * name;  // Name string copy.
+       uint   base;  // Default amount of points per entity.
+       uint   limit; // After this point, points won't increase.
+} * dungeon_attribute_definition;
+
+typedef struct {
+       char * name;  // Name string copy.
+       uint   base;  // Default amount of points per entity.
+       uint   limit; // After this point, points won't increase.
+} * dungeon_skill_definition;
+
+typedef struct {
+       char * name;  // Name string copy.
+       uint   base;  // Default amount of points per entity.
+       uint   limit; // After this point, points won't increase.
+       uint   value; // Constant trade value per index 0.
+       uint   trade; // Trade rate for acquiring the resource.
+} * dungeon_resource_definition;
+
+typedef struct {
+       char * name; // Name string copy.
+} * dungeon_item_slot_definition;
+
+typedef struct {
+       char * name;   // Name string copy.
+       uint   slot;   // Index in item slot array.
+       uint   effect; // Index in effect array.
+} * dungeon_item_definition;
+
+typedef struct {
+       uint                           biome_count;
+       uint                           landmark_count;
+       uint                           expertise_count;
+       uint                           attribute_count;
+       uint                           skill_count;
+       uint                           resource_count;
+       uint                           item_slot_count;
+       uint                           item_count;
+       dungeon_biome_definition     * biome_array;
+       dungeon_landmark_definition  * landmark_array;
+       dungeon_expertise_definition * expertise_array;
+       dungeon_attribute_definition * attribute_array;
+       dungeon_skill_definition     * skill_array;
+       dungeon_resource_definition  * resource_array;
+       dungeon_item_slot_definition * item_slot_array;
+       dungeon_item_definition      * item_array;
+} * dungeon_structure;
+
+static uint dungeon_biome_define (dungeon_structure dungeon, const char * name, uint temperature, uint humidity) {
+       dungeon_biome_definition biome = arena_add (sizeof (* biome));
+
+       fatal_failure (dungeon == null, "biome_define: Dungeon is not configured.");
+       fatal_failure (name    == null, "biome_define: Name is null pointer.");
+
+       string_copy ((biome->name = arena_add ((string_length (name) + 1) * sizeof (* biome->name))), name);
+
+       biome->temperature = temperature;
+       biome->humidity    = humidity;
+
+       dungeon->biome_count += 1;
+
+       dungeon->biome_array [dungeon->biome_count - 1] = biome;
+
+       return (dungeon->biome_count - 1);
+}
+
+static char * dungeon_biome_name        (dungeon_structure dungeon, uint index) { return (dungeon->biome_array [index]->name);        }
+static uint   dungeon_biome_temperature (dungeon_structure dungeon, uint index) { return (dungeon->biome_array [index]->temperature); }
+static uint   dungeon_biome_humidity    (dungeon_structure dungeon, uint index) { return (dungeon->biome_array [index]->humidity);    }
+
+static uint dungeon_landmark_define (dungeon_structure dungeon, const char * name, uint biome, bool clip) {
+       dungeon_landmark_definition landmark = arena_add (sizeof (* landmark));
+
+       fatal_failure (dungeon == null, "landmark_define: Dungeon is not configured.");
+       fatal_failure (name    == null, "landmark_define: Name is null pointer.");
+
+       string_copy ((landmark->name = arena_add ((string_length (name) + 1) * sizeof (* landmark->name))), name);
+
+       landmark->biome = biome;
+       landmark->clip  = clip;
+
+       dungeon->landmark_count += 1;
+
+       dungeon->landmark_array [dungeon->landmark_count - 1] = landmark;
+
+       return (dungeon->landmark_count - 1);
+}
+
+static char * dungeon_landmark_name  (dungeon_structure dungeon, uint index) { return (dungeon->landmark_array [index]->name);  }
+static uint   dungeon_landmark_biome (dungeon_structure dungeon, uint index) { return (dungeon->landmark_array [index]->biome); }
+static bool   dungeon_landmark_clip  (dungeon_structure dungeon, uint index) { return (dungeon->landmark_array [index]->clip);  }
+
+static uint dungeon_expertise_define (dungeon_structure dungeon, const char * name) {
+       dungeon_expertise_definition expertise = arena_add (sizeof (* expertise));
+
+       fatal_failure (dungeon == null, "expertise_define: Dungeon is not configured.");
+       fatal_failure (name    == null, "expertise_define: Name is null pointer.");
+
+       string_copy ((expertise->name = arena_add ((string_length (name) + 1) * sizeof (* expertise->name))), name);
+
+       dungeon->expertise_count += 1;
+
+       dungeon->expertise_array [dungeon->expertise_count - 1] = expertise;
+
+       return (dungeon->expertise_count - 1);
+}
+
+static char * dungeon_expertise_name (dungeon_structure dungeon, uint index) { return (dungeon->expertise_array [index]->name); }
+
+static uint dungeon_attribute_define (dungeon_structure dungeon, const char * name, uint base, uint limit) {
+       dungeon_attribute_definition attribute = arena_add (sizeof (* attribute));
+
+       fatal_failure (dungeon == null, "attribute_define: Dungeon is not configured.");
+       fatal_failure (name    == null, "attribute_define: Name is null pointer.");
+
+       string_copy ((attribute->name = arena_add ((string_length (name) + 1) * sizeof (* attribute->name))), name);
+
+       attribute->base  = base;
+       attribute->limit = limit;
+
+       dungeon->attribute_count += 1;
+
+       dungeon->attribute_array [dungeon->attribute_count - 1] = attribute;
+
+       return (dungeon->attribute_count - 1);
+}
+
+static char * dungeon_attribute_name  (dungeon_structure dungeon, uint index) { return (dungeon->attribute_array [index]->name);  }
+static uint   dungeon_attribute_base  (dungeon_structure dungeon, uint index) { return (dungeon->attribute_array [index]->base);  }
+static uint   dungeon_attribute_limit (dungeon_structure dungeon, uint index) { return (dungeon->attribute_array [index]->limit); }
+
+static uint dungeon_skill_define (dungeon_structure dungeon, const char * name, uint base, uint limit) {
+       dungeon_skill_definition skill = arena_add (sizeof (* skill));
+
+       fatal_failure (dungeon == null, "skill_define: Dungeon is not configured.");
+       fatal_failure (name    == null, "skill_define: Name is null pointer.");
+
+       string_copy ((skill->name = arena_add ((string_length (name) + 1) * sizeof (* skill->name))), name);
+
+       skill->base  = base;
+       skill->limit = limit;
+
+       dungeon->skill_count += 1;
+
+       dungeon->skill_array [dungeon->skill_count - 1] = skill;
+
+       return (dungeon->skill_count - 1);
+}
+
+static char * dungeon_skill_name  (dungeon_structure dungeon, uint index) { return (dungeon->skill_array [index]->name);  }
+static uint   dungeon_skill_base  (dungeon_structure dungeon, uint index) { return (dungeon->skill_array [index]->base);  }
+static uint   dungeon_skill_limit (dungeon_structure dungeon, uint index) { return (dungeon->skill_array [index]->limit); }
+
+static uint dungeon_resource_define (dungeon_structure dungeon, const char * name, uint base, uint limit, uint value, uint trade) {
+       dungeon_resource_definition resource = arena_add (sizeof (* resource));
+
+       fatal_failure (dungeon == null, "resource_define: Dungeon is not configured.");
+       fatal_failure (name    == null, "resource_define: Name is null pointer.");
+
+       string_copy ((resource->name = arena_add ((string_length (name) + 1) * sizeof (* resource->name))), name);
+
+       resource->base  = base;
+       resource->limit = limit;
+       resource->value = value;
+       resource->trade = trade;
+
+       dungeon->resource_count += 1;
+
+       dungeon->resource_array [dungeon->resource_count - 1] = resource;
+
+       return (dungeon->resource_count - 1);
+}
+
+static char * dungeon_resource_name  (dungeon_structure dungeon, uint index) { return (dungeon->resource_array [index]->name);  }
+static uint   dungeon_resource_base  (dungeon_structure dungeon, uint index) { return (dungeon->resource_array [index]->base);  }
+static uint   dungeon_resource_limit (dungeon_structure dungeon, uint index) { return (dungeon->resource_array [index]->limit); }
+static uint   dungeon_resource_value (dungeon_structure dungeon, uint index) { return (dungeon->resource_array [index]->value); }
+static uint   dungeon_resource_trade (dungeon_structure dungeon, uint index) { return (dungeon->resource_array [index]->trade); }
+
+static uint dungeon_item_slot_define (dungeon_structure dungeon, const char * name) {
+       dungeon_item_slot_definition item_slot = arena_add (sizeof (* item_slot));
+
+       fatal_failure (dungeon == null, "item_slot_define: Dungeon is not configured.");
+       fatal_failure (name    == null, "item_slot_define: Name is null pointer.");
+
+       string_copy ((item_slot->name = arena_add ((string_length (name) + 1) * sizeof (* item_slot->name))), name);
+
+       dungeon->item_slot_count += 1;
+
+       dungeon->item_slot_array [dungeon->item_slot_count - 1] = item_slot;
+
+       return (dungeon->item_slot_count - 1);
+}
+
+static char * dungeon_item_slot_name (dungeon_structure dungeon, uint index) { return (dungeon->item_slot_array [index]->name); }
+
+static uint dungeon_item_define (dungeon_structure dungeon, const char * name, uint slot, uint effect) {
+       dungeon_item_definition item = arena_add (sizeof (* item));
+
+       fatal_failure (dungeon == null, "item_define: Dungeon is not configured.");
+       fatal_failure (name    == null, "item_define: Name is null pointer.");
+
+       string_copy ((item->name = arena_add ((string_length (name) + 1) * sizeof (* item->name))), name);
+
+       item->slot   = slot;
+       item->effect = effect;
+
+       dungeon->item_count += 1;
+
+       dungeon->item_array [dungeon->item_count - 1] = item;
+
+       return (dungeon->item_count - 1);
+}
+
+static char * dungeon_item_name   (dungeon_structure dungeon, uint index) { return (dungeon->item_array [index]->name);   }
+static uint   dungeon_item_slot   (dungeon_structure dungeon, uint index) { return (dungeon->item_array [index]->slot);   }
+static uint   dungeon_item_effect (dungeon_structure dungeon, uint index) { return (dungeon->item_array [index]->effect); }
+
+static dungeon_structure dungeon_configure (uint biome_limit, uint landmark_limit, uint expertise_limit, uint attribute_limit, uint skill_limit,
+                                            uint resource_limit, uint item_slot_limit, uint item_limit) {
+       dungeon_structure dungeon = arena_add (sizeof (* dungeon));
+
+       dungeon->biome_array     = arena_add (biome_limit     * sizeof (* dungeon->biome_array));
+       dungeon->landmark_array  = arena_add (landmark_limit  * sizeof (* dungeon->landmark_array));
+       dungeon->expertise_array = arena_add (expertise_limit * sizeof (* dungeon->expertise_array));
+       dungeon->attribute_array = arena_add (attribute_limit * sizeof (* dungeon->attribute_array));
+       dungeon->skill_array     = arena_add (skill_limit     * sizeof (* dungeon->skill_array));
+       dungeon->resource_array  = arena_add (resource_limit  * sizeof (* dungeon->resource_array));
+       dungeon->item_slot_array = arena_add (item_slot_limit * sizeof (* dungeon->item_slot_array));
+       dungeon->item_array      = arena_add (item_limit      * sizeof (* dungeon->item_array));
+
+       return (dungeon);
+}
diff --git a/xuxuxu.c b/xuxuxu.c
new file mode 100755 (executable)
index 0000000..ee77e9c
--- /dev/null
+++ b/xuxuxu.c
@@ -0,0 +1,130 @@
+#include <xolatile/xtandard.h>
+#include <xolatile/xyntax.h>
+#include <xolatile/xormat/png.h>
+
+#define foreground (0xffccccccu)
+#define background (0xff181818u)
+
+#define font_indent ( 8)
+#define font_width  ( 8)
+#define font_height ( 8)
+#define font_count  (96)
+
+static uint * render = null;
+static uint   colour = foreground;
+
+static uint width  = 0;
+static uint height = 0;
+static uint x      = 0;
+static uint y      = 0;
+
+static void render_character (char character) {
+       const ulong font_code [font_count] = {
+               0x0000000000000000,             0x00180018183c3c18,             0x0000000000363636,             0x006c6cfe6cfe6c6c,
+               0x00187ed07c16fc30,             0x0060660c18306606,             0x00dc66b61c36361c,             0x0000000000181818,
+               0x0030180c0c0c1830,             0x000c18303030180c,             0x0000187e3c7e1800,             0x000018187e181800,
+               0x0c18180000000000,             0x000000007e000000,             0x0018180000000000,             0x0000060c18306000,
+               0x003c666e7e76663c,             0x007e181818181c18,             0x007e0c183060663c,             0x003c66603860663c,
+               0x0030307e363c3830,             0x003c6660603e067e,             0x003c66663e060c38,             0x000c0c0c1830607e,
+               0x003c66663c66663c,             0x001c30607c66663c,             0x0018180018180000,             0x0c18180018180000,
+               0x0030180c060c1830,             0x0000007e007e0000,             0x000c18306030180c,             0x001800181830663c,
+               0x003c06765676663c,             0x006666667e66663c,             0x003e66663e66663e,             0x003c66060606663c,
+               0x001e36666666361e,             0x007e06063e06067e,             0x000606063e06067e,             0x003c66667606663c,
+               0x006666667e666666,             0x007e18181818187e,             0x001c36303030307c,             0x0066361e0e1e3666,
+               0x007e060606060606,             0x00c6c6d6d6feeec6,             0x006666767e6e6666,             0x003c66666666663c,
+               0x000606063e66663e,             0x006c36566666663c,             0x006666363e66663e,             0x003c66603c06663c,
+               0x001818181818187e,             0x003c666666666666,             0x00183c6666666666,             0x00c6eefed6d6c6c6,
+               0x0066663c183c6666,             0x001818183c666666,             0x007e060c1830607e,             0x003e06060606063e,
+               0x00006030180c0600,             0x007c60606060607c,             0x000000000000663c,             0xffff000000000000,
+               0x000000000030180c,             0x007c667c603c0000,             0x003e6666663e0606,             0x003c6606663c0000,
+               0x007c6666667c6060,             0x003c067e663c0000,             0x000c0c0c3e0c0c38,             0x3c607c66667c0000,
+               0x00666666663e0606,             0x003c1818181c0018,             0x0e181818181c0018,             0x0066361e36660606,
+               0x003c18181818181c,             0x00c6d6d6fe6c0000,             0x00666666663e0000,             0x003c6666663c0000,
+               0x06063e66663e0000,             0xe0607c66667c0000,             0x000606066e360000,             0x003e603c067c0000,
+               0x00380c0c0c3e0c0c,             0x007c666666660000,             0x00183c6666660000,             0x006cfed6d6c60000,
+               0x00663c183c660000,             0x3c607c6666660000,             0x007e0c18307e0000,             0x003018180e181830,
+               0x0018181818181818,             0x000c18187018180c,             0x000000000062d68c,             0x0000000000000000
+       };
+
+       for (uint offset = 0; offset < font_width * font_height; ++offset) {
+               uint u = offset / font_width + y;
+               uint v = offset % font_width + x;
+
+               render [u * width + v] = ((font_code [(uint) (character - ' ')] >> offset) % 2) ? colour : background;
+       }
+
+       x += font_width + 1;
+}
+
+static void render_string (const char * string, uint length) {
+       for (uint offset = 0; offset < length; ++offset) {
+               if (string [offset] == '\t') {
+                       x += font_width * font_indent;
+               } else if (string [offset] == '\n') {
+                       y += font_height + 1;
+                       x  = 1;
+               } else {
+                       render_character (string [offset]);
+               }
+       }
+}
+
+int main (void) {
+       uint   index  = 0;
+       uint   length = 0;
+       char * buffer = null;
+
+       const char separator [] = ".,:;<=>+-*/%!&~^()[]{}'\" \t\r\n";
+
+       const char * keywords [] = {
+               "register", "volatile", "auto",     "const",    "static",   "extern",   "if",       "else",
+               "do",       "while",    "for",      "continue", "switch",   "case",     "default",  "break",
+               "enum",     "union",    "struct",   "typedef",  "goto",     "void",     "return",   "sizeof",
+               "char",     "short",    "int",      "long",     "signed",   "unsigned", "float",    "double"
+       };
+
+       syntax_structure * syntax = syntax_initialize (0);
+
+       syntax_define (syntax, false, false, "#",                  "\n", '\\', 0xff3377aa, 0);
+       syntax_define (syntax, false, false, "//",                 "\n", '\0', 0xff777777, 0);
+       syntax_define (syntax, false, false, "/*",                 "*/", '\0', 0xff777777, 0);
+       syntax_define (syntax, false, false, "'",                  "'",  '\\', 0xff9933cc, 0);
+       syntax_define (syntax, false, false, "\"",                 "\"", '\\', 0xffcc3399, 0);
+       syntax_define (syntax, true,  false, ".,:;<=>+-*/%!&~^?|", "",   '\0', 0xffccaa33, 0);
+       syntax_define (syntax, true,  false, "(){}[]",             "",   '\0', 0xffcc3333, 0);
+
+       for (ulong word = 0; word < array_length (keywords); ++word) {
+               syntax_define (syntax, false, true, keywords [word], separator, '\0', 0xff33aacc, 0);
+       }
+
+       syntax_define (syntax, true, true, "0123456789",                                            separator, '\0', 0xffcc77cc, 0);
+       syntax_define (syntax, true, true, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_", separator, '\0', 0xffcccccc, 0);
+
+       buffer = record ();
+
+       width  = string_full_width  (buffer, font_indent) * (font_width  + 1) + 1;
+       height = string_full_height (buffer)              * (font_height + 1) + 1;
+
+       render = allocate (4 * width * height);
+
+       for (uint offset = 0; offset < width * height; ++offset) {
+               render [offset] = background;
+       }
+
+       for (uint offset = 0; buffer [offset] != '\0'; offset += length) {
+               index = syntax_select (syntax, & buffer [offset], & length);
+
+               colour = syntax->colour [index];
+
+               render_string (& buffer [offset], length);
+       }
+
+       png_image_export ("xuxuxu.png", render, width, height);
+
+       syntax = syntax_deinitialize (syntax);
+
+       buffer = deallocate (buffer);
+       render = deallocate (render);
+
+       return (log_success);
+}
diff --git a/xyntax.h b/xyntax.h
new file mode 100755 (executable)
index 0000000..849d44c
--- /dev/null
+++ b/xyntax.h
@@ -0,0 +1,175 @@
+///                   _
+/// __  ___   _ _ __ | |_ __ ___  __
+/// \ \/ / | | | '_ \| __/ _` \ \/ /
+///  >  <| |_| | | | | || (_| |>  <
+/// /_/\_\\__, |_| |_|\__\__,_/_/\_\
+///       |___/
+///
+/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
+///
+/// xolatile@chud.cyou - xyntax - Tiny, unsafe and somewhat insane unity header for generic syntax definition.
+///
+/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
+/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
+///
+/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
+/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
+/// for more details, if you dare, it is a lot of text that nobody wants to read...
+
+typedef struct {
+       uint     count;
+       uint     limit;
+       bool   * enrange;
+       bool   * derange;
+       char * * begin;
+       char * * end;
+       char   * escape;
+       uint   * colour;
+       uint   * effect;
+} syntax_structure;
+
+static syntax_structure * syntax_initialize (uint limit) {
+       syntax_structure * syntax = allocate (sizeof (* syntax));
+
+       syntax->limit = limit;
+
+       if (limit != 0) {
+               syntax->enrange = allocate (syntax->limit * sizeof (* syntax->enrange));
+               syntax->derange = allocate (syntax->limit * sizeof (* syntax->derange));
+               syntax->begin   = allocate (syntax->limit * sizeof (* syntax->begin));
+               syntax->end     = allocate (syntax->limit * sizeof (* syntax->end));
+               syntax->escape  = allocate (syntax->limit * sizeof (* syntax->escape));
+               syntax->colour  = allocate (syntax->limit * sizeof (* syntax->colour));
+               syntax->effect  = allocate (syntax->limit * sizeof (* syntax->effect));
+       }
+
+       return (syntax);
+}
+
+static syntax_structure * syntax_deinitialize (syntax_structure * syntax) {
+       for (uint index = 0; index < syntax->count; ++index) {
+               syntax->begin [index] = deallocate (syntax->begin [index]);
+               syntax->end   [index] = deallocate (syntax->end   [index]);
+       }
+
+       syntax->enrange = deallocate (syntax->enrange);
+       syntax->derange = deallocate (syntax->derange);
+       syntax->begin   = deallocate (syntax->begin);
+       syntax->end     = deallocate (syntax->end);
+       syntax->escape  = deallocate (syntax->escape);
+       syntax->colour  = deallocate (syntax->colour);
+       syntax->effect  = deallocate (syntax->effect);
+
+       return (deallocate (syntax));
+}
+
+static uint syntax_define (syntax_structure * syntax, bool enrange, bool derange, const char * begin, const char * end, char escape,
+                           uint colour, uint effect) {
+       ++syntax->count;
+
+       uint current = syntax->count - 1;
+
+       fatal_failure (begin == null, "syntax_define: Begin string is null pointer.");
+       fatal_failure (end   == null, "syntax_define: End string is null pointer.");
+
+       fatal_failure (syntax->count >= syntax->limit, "syntax_define: Reached the hardcoded limit.");
+
+       if (syntax->limit == 0) {
+               syntax->enrange = reallocate (syntax->enrange, syntax->count * sizeof (* syntax->enrange));
+               syntax->derange = reallocate (syntax->derange, syntax->count * sizeof (* syntax->derange));
+               syntax->begin   = reallocate (syntax->begin,   syntax->count * sizeof (* syntax->begin));
+               syntax->end     = reallocate (syntax->end,     syntax->count * sizeof (* syntax->end));
+               syntax->escape  = reallocate (syntax->escape,  syntax->count * sizeof (* syntax->escape));
+               syntax->colour  = reallocate (syntax->colour,  syntax->count * sizeof (* syntax->colour));
+               syntax->effect  = reallocate (syntax->effect,  syntax->count * sizeof (* syntax->effect));
+       }
+
+       syntax->begin [current] = allocate ((string_length (begin) + 1) * sizeof (* * syntax->begin));
+       syntax->end   [current] = allocate ((string_length (end)   + 1) * sizeof (* * syntax->end));
+
+       syntax->enrange [current] = enrange;
+       syntax->derange [current] = derange;
+       syntax->escape  [current] = escape;
+       syntax->colour  [current] = colour;
+       syntax->effect  [current] = effect;
+
+       string_copy (syntax->begin [current], begin);
+       string_copy (syntax->end   [current], end);
+
+       return (current);
+}
+
+static uint syntax_select (syntax_structure * syntax, const char * string, uint * length) {
+       uint offset = 0;
+       uint subset = 0;
+       uint select = 0;
+
+       ulong begin_length = 0;
+       ulong end_length   = 0;
+
+       for (; select != syntax->count; ++select) {
+               begin_length = string_length (syntax->begin [select]);
+
+               if (! syntax->enrange [select]) {
+                       if (! syntax->derange [select]) {
+                               if (string_compare_limit (string, syntax->begin [select], begin_length)) {
+                                       break;
+                               }
+                       } else {
+                               if ((string_compare_limit    (string, syntax->begin [select], begin_length))
+                               &&  (character_compare_array (string [offset + begin_length], syntax->end [select]))) {
+                                       break;
+                               }
+                       }
+               } else {
+                       for (subset = 0; subset != begin_length; ++subset) {
+                               if (string [offset] == syntax->begin [select] [subset]) {
+                                       goto selected;
+                               }
+                       }
+               }
+       }
+
+       selected:
+
+       if (select >= syntax->count) {
+               * length = 1;
+
+               return (syntax->count);
+       }
+
+       end_length = string_length (syntax->end [select]);
+
+       for (offset = 1; string [offset - 1] != character_null; ++offset) {
+               if (string [offset] == syntax->escape [select]) {
+                       ++offset;
+                       continue;
+               }
+
+               if (syntax->derange [select]) {
+                       subset = 0;
+                       if (end_length == 0) {
+                               break;
+                       } do {
+                               if (string [offset] == syntax->end [select] [subset]) {
+                                       * length = offset;
+                                       goto finished;
+                               }
+                       } while (++subset != end_length);
+               } else {
+                       if (end_length != 0) {
+                               if (string_compare_limit (& string [offset], syntax->end [select], end_length)) {
+                                       * length = offset + end_length;
+                                       return (select);
+                               }
+                       } else {
+                               * length = 1;
+                               return (select);
+                       }
+               }
+       }
+
+       finished:
+
+       return (select);
+}