From 6e21f5457cf1aa57d45cd86031aa237d73cac69d Mon Sep 17 00:00:00 2001 From: xolatile Date: Sun, 6 Apr 2025 16:01:15 +0200 Subject: [PATCH] Just dumped everything because... --- .gitignore | 8 + LICENSE | 625 ++++++ README.md | 41 + compile.sh | 19 + install.sh | 53 + test | Bin 0 -> 63264 bytes test.c | 79 + xachine.h | 456 +++++ xanguage.h | 201 ++ xanguage/ada.h | 31 + xanguage/bash.h | 24 + xanguage/c++.h | 53 + xanguage/c.h | 49 + xanguage/common.h | 9 + xanguage/d.h | 49 + xanguage/eaxhla.h | 79 + xanguage/flat.h | 66 + xanguage/fortran.h | 47 + xanguage/go.h | 46 + xanguage/haskell.h | 34 + xanguage/lua.h | 50 + xanguage/pascal.h | 29 + xanguage/python.h | 47 + xanguage/valgrind.h | 25 + xanual/adc.md | 52 + xanual/add.md | 48 + xanual/and.md | 45 + xanual/call.md | 201 ++ xanual/cmovcc.md | 121 ++ xanual/cmp.md | 45 + xanual/dec.md | 31 + xanual/div.md | 28 + xanual/enter.md | 46 + xanual/idiv.md | 28 + xanual/imul.md | 66 + xanual/inc.md | 31 + xanual/jcc.md | 147 ++ xanual/jmp.md | 103 + xanual/leave.md | 20 + xanual/mov.md | 78 + xanual/mul.md | 28 + xanual/neg.md | 26 + xanual/nop.md | 40 + xanual/not.md | 26 + xanual/or.md | 45 + xanual/pop.md | 66 + xanual/push.md | 55 + xanual/ret.md | 52 + xanual/rot.md | 94 + xanual/sbb.md | 54 + xanual/setcc.md | 89 + xanual/sft.md | 110 ++ xanual/sub.md | 48 + xanual/syscall.md | 27 + xanual/sysenter.md | 61 + xanual/sysexit.md | 46 + xanual/sysret.md | 42 + xanual/template.md | 15 + xanual/xor.md | 44 + xaptor | Bin 0 -> 81672 bytes xaptor.c | 44 + xaptor.h | 679 +++++++ xarbon.c | 274 +++ xarticle.h | 170 ++ xatrix.h | 510 +++++ xcript.h | 383 ++++ xector.h | 388 ++++ xhallenge.c | 531 +++++ xhallenge_list.cfg | 433 +++++ xiasma.h | 694 +++++++ xighlight.c | 127 ++ xogueout | Bin 0 -> 35224 bytes xogueout.c | 50 + xommon.h | 666 +++++++ xop.c | 43 + xormat.h | 122 ++ xormat/jxl.h | 68 + xormat/png.h | 106 + xpenal.h | 19 + xpengl.h | 1209 ++++++++++++ xphere.h | 86 + xprite.h | 131 ++ xrocessor.h | 303 +++ xross.h | 190 ++ xscii.c | 99 + xtandard.h | 1136 +++++++++++ xui.h | 392 ++++ xui/common/fullscreen_off.png | Bin 0 -> 217 bytes xui/common/fullscreen_on.png | Bin 0 -> 219 bytes xui/common/map_preview_panel_off.png | Bin 0 -> 200 bytes xui/common/map_preview_panel_on.png | Bin 0 -> 202 bytes xui/common/monospace.png | Bin 0 -> 6376 bytes xui/common/palette.png | Bin 0 -> 210 bytes xui/common/regular.png | Bin 0 -> 9327 bytes xui/common/status_preview_panel_off.png | Bin 0 -> 209 bytes xui/common/status_preview_panel_on.png | Bin 0 -> 211 bytes xui/common/text_box_panel_off.png | Bin 0 -> 178 bytes xui/common/text_box_panel_on.png | Bin 0 -> 180 bytes xui/dwarf/button_left.png | Bin 0 -> 113 bytes xui/dwarf/button_lower.png | Bin 0 -> 114 bytes xui/dwarf/button_lower_left.png | Bin 0 -> 145 bytes xui/dwarf/button_lower_right.png | Bin 0 -> 138 bytes xui/dwarf/button_middle.png | Bin 0 -> 100 bytes xui/dwarf/button_right.png | Bin 0 -> 113 bytes xui/dwarf/button_upper.png | Bin 0 -> 118 bytes xui/dwarf/button_upper_left.png | Bin 0 -> 136 bytes xui/dwarf/button_upper_right.png | Bin 0 -> 142 bytes xui/dwarf/check_box_off.png | Bin 0 -> 383 bytes xui/dwarf/check_box_on.png | Bin 0 -> 450 bytes xui/dwarf/cursor.png | Bin 0 -> 378 bytes xui/dwarf/end_turn_button.png | Bin 0 -> 1351 bytes xui/dwarf/fill_bar_base.png | Bin 0 -> 131 bytes xui/dwarf/fill_bar_left.png | Bin 0 -> 825 bytes xui/dwarf/fill_bar_middle.png | Bin 0 -> 156 bytes xui/dwarf/fill_bar_right.png | Bin 0 -> 328 bytes xui/dwarf/frame_left.png | Bin 0 -> 114 bytes xui/dwarf/frame_lower.png | Bin 0 -> 110 bytes xui/dwarf/frame_lower_left.png | Bin 0 -> 145 bytes xui/dwarf/frame_lower_right.png | Bin 0 -> 137 bytes xui/dwarf/frame_right.png | Bin 0 -> 110 bytes xui/dwarf/frame_upper.png | Bin 0 -> 109 bytes xui/dwarf/frame_upper_left.png | Bin 0 -> 139 bytes xui/dwarf/frame_upper_right.png | Bin 0 -> 146 bytes xui/dwarf/icon_frame.png | Bin 0 -> 303 bytes xui/dwarf/menu_left.png | Bin 0 -> 113 bytes xui/dwarf/menu_lower.png | Bin 0 -> 114 bytes xui/dwarf/menu_lower_left.png | Bin 0 -> 145 bytes xui/dwarf/menu_lower_right.png | Bin 0 -> 138 bytes xui/dwarf/menu_middle.png | Bin 0 -> 100 bytes xui/dwarf/menu_right.png | Bin 0 -> 113 bytes xui/dwarf/menu_upper.png | Bin 0 -> 118 bytes xui/dwarf/menu_upper_left.png | Bin 0 -> 136 bytes xui/dwarf/menu_upper_right.png | Bin 0 -> 142 bytes xui/dwarf/overicon_frame.png | Bin 0 -> 273 bytes xui/dwarf/scroll_bar_lower.png | Bin 0 -> 277 bytes xui/dwarf/scroll_bar_middle.png | Bin 0 -> 139 bytes xui/dwarf/scroll_bar_slider.png | Bin 0 -> 273 bytes xui/dwarf/scroll_bar_upper.png | Bin 0 -> 287 bytes xui/dwarf/separator_center.png | Bin 0 -> 273 bytes xui/dwarf/separator_left.png | Bin 0 -> 229 bytes xui/dwarf/separator_middle.png | Bin 0 -> 125 bytes xui/dwarf/separator_right.png | Bin 0 -> 248 bytes xui/dwarf/status_left.png | Bin 0 -> 126 bytes xui/dwarf/status_lower.png | Bin 0 -> 127 bytes xui/dwarf/status_lower_left.png | Bin 0 -> 372 bytes xui/dwarf/status_lower_right.png | Bin 0 -> 375 bytes xui/dwarf/status_middle.png | Bin 0 -> 124 bytes xui/dwarf/status_right.png | Bin 0 -> 126 bytes xui/dwarf/status_upper.png | Bin 0 -> 127 bytes xui/dwarf/status_upper_left.png | Bin 0 -> 349 bytes xui/dwarf/status_upper_right.png | Bin 0 -> 389 bytes xui/dwarf/tiny_fill_bar_base.png | Bin 0 -> 137 bytes xui/dwarf/tiny_fill_bar_left.png | Bin 0 -> 429 bytes xui/dwarf/tiny_fill_bar_middle.png | Bin 0 -> 166 bytes xui/dwarf/tiny_fill_bar_right.png | Bin 0 -> 354 bytes xui/dwarf/title_bar_left.png | Bin 0 -> 539 bytes xui/dwarf/title_bar_middle.png | Bin 0 -> 155 bytes xui/dwarf/title_bar_right.png | Bin 0 -> 434 bytes xui/dwarf/ubericon_frame.png | Bin 0 -> 174 bytes xui/dwarf/window_left.png | Bin 0 -> 492 bytes xui/dwarf/window_lower.png | Bin 0 -> 425 bytes xui/dwarf/window_lower_left.png | Bin 0 -> 1439 bytes xui/dwarf/window_lower_right.png | Bin 0 -> 1466 bytes xui/dwarf/window_right.png | Bin 0 -> 492 bytes xui/dwarf/window_upper.png | Bin 0 -> 425 bytes xui/dwarf/window_upper_left.png | Bin 0 -> 1434 bytes xui/dwarf/window_upper_right.png | Bin 0 -> 1744 bytes xui/fairy/button_left.png | Bin 0 -> 116 bytes xui/fairy/button_lower.png | Bin 0 -> 124 bytes xui/fairy/button_lower_left.png | Bin 0 -> 156 bytes xui/fairy/button_lower_right.png | Bin 0 -> 182 bytes xui/fairy/button_middle.png | Bin 0 -> 100 bytes xui/fairy/button_right.png | Bin 0 -> 116 bytes xui/fairy/button_upper.png | Bin 0 -> 123 bytes xui/fairy/button_upper_left.png | Bin 0 -> 161 bytes xui/fairy/button_upper_right.png | Bin 0 -> 179 bytes xui/fairy/check_box_off.png | Bin 0 -> 186 bytes xui/fairy/check_box_on.png | Bin 0 -> 261 bytes xui/fairy/cursor.png | Bin 0 -> 344 bytes xui/fairy/end_turn_button.png | Bin 0 -> 1223 bytes xui/fairy/fill_bar_base.png | Bin 0 -> 155 bytes xui/fairy/fill_bar_left.png | Bin 0 -> 381 bytes xui/fairy/fill_bar_middle.png | Bin 0 -> 179 bytes xui/fairy/fill_bar_right.png | Bin 0 -> 213 bytes xui/fairy/frame_left.png | Bin 0 -> 109 bytes xui/fairy/frame_lower.png | Bin 0 -> 105 bytes xui/fairy/frame_lower_left.png | Bin 0 -> 127 bytes xui/fairy/frame_lower_right.png | Bin 0 -> 136 bytes xui/fairy/frame_right.png | Bin 0 -> 109 bytes xui/fairy/frame_upper.png | Bin 0 -> 104 bytes xui/fairy/frame_upper_left.png | Bin 0 -> 129 bytes xui/fairy/frame_upper_right.png | Bin 0 -> 124 bytes xui/fairy/icon_frame.png | Bin 0 -> 205 bytes xui/fairy/menu_left.png | Bin 0 -> 122 bytes xui/fairy/menu_lower.png | Bin 0 -> 127 bytes xui/fairy/menu_lower_left.png | Bin 0 -> 163 bytes xui/fairy/menu_lower_right.png | Bin 0 -> 179 bytes xui/fairy/menu_middle.png | Bin 0 -> 107 bytes xui/fairy/menu_right.png | Bin 0 -> 123 bytes xui/fairy/menu_upper.png | Bin 0 -> 125 bytes xui/fairy/menu_upper_left.png | Bin 0 -> 171 bytes xui/fairy/menu_upper_right.png | Bin 0 -> 175 bytes xui/fairy/overicon_frame.png | Bin 0 -> 193 bytes xui/fairy/scroll_bar_lower.png | Bin 0 -> 316 bytes xui/fairy/scroll_bar_middle.png | Bin 0 -> 137 bytes xui/fairy/scroll_bar_slider.png | Bin 0 -> 338 bytes xui/fairy/scroll_bar_upper.png | Bin 0 -> 313 bytes xui/fairy/separator_center.png | Bin 0 -> 338 bytes xui/fairy/separator_left.png | Bin 0 -> 191 bytes xui/fairy/separator_middle.png | Bin 0 -> 122 bytes xui/fairy/separator_right.png | Bin 0 -> 132 bytes xui/fairy/status_left.png | Bin 0 -> 150 bytes xui/fairy/status_lower.png | Bin 0 -> 153 bytes xui/fairy/status_lower_left.png | Bin 0 -> 409 bytes xui/fairy/status_lower_right.png | Bin 0 -> 405 bytes xui/fairy/status_middle.png | Bin 0 -> 159 bytes xui/fairy/status_right.png | Bin 0 -> 150 bytes xui/fairy/status_upper.png | Bin 0 -> 153 bytes xui/fairy/status_upper_left.png | Bin 0 -> 382 bytes xui/fairy/status_upper_right.png | Bin 0 -> 475 bytes xui/fairy/tiny_fill_bar_base.png | Bin 0 -> 160 bytes xui/fairy/tiny_fill_bar_left.png | Bin 0 -> 344 bytes xui/fairy/tiny_fill_bar_middle.png | Bin 0 -> 188 bytes xui/fairy/tiny_fill_bar_right.png | Bin 0 -> 353 bytes xui/fairy/title_bar_left.png | Bin 0 -> 554 bytes xui/fairy/title_bar_middle.png | Bin 0 -> 206 bytes xui/fairy/title_bar_right.png | Bin 0 -> 288 bytes xui/fairy/ubericon_frame.png | Bin 0 -> 155 bytes xui/fairy/window_left.png | Bin 0 -> 262 bytes xui/fairy/window_lower.png | Bin 0 -> 184 bytes xui/fairy/window_lower_left.png | Bin 0 -> 992 bytes xui/fairy/window_lower_right.png | Bin 0 -> 924 bytes xui/fairy/window_right.png | Bin 0 -> 262 bytes xui/fairy/window_upper.png | Bin 0 -> 184 bytes xui/fairy/window_upper_left.png | Bin 0 -> 969 bytes xui/fairy/window_upper_right.png | Bin 0 -> 1060 bytes xui/fullscreen_off.png | Bin 0 -> 217 bytes xui/fullscreen_on.png | Bin 0 -> 219 bytes xui/gnoll/button_left.png | Bin 0 -> 115 bytes xui/gnoll/button_lower.png | Bin 0 -> 116 bytes xui/gnoll/button_lower_left.png | Bin 0 -> 137 bytes xui/gnoll/button_lower_right.png | Bin 0 -> 136 bytes xui/gnoll/button_middle.png | Bin 0 -> 100 bytes xui/gnoll/button_right.png | Bin 0 -> 112 bytes xui/gnoll/button_upper.png | Bin 0 -> 117 bytes xui/gnoll/button_upper_left.png | Bin 0 -> 133 bytes xui/gnoll/button_upper_right.png | Bin 0 -> 140 bytes xui/gnoll/check_box_off.png | Bin 0 -> 359 bytes xui/gnoll/check_box_on.png | Bin 0 -> 375 bytes xui/gnoll/cursor.png | Bin 0 -> 396 bytes xui/gnoll/end_turn_button.png | Bin 0 -> 1098 bytes xui/gnoll/fill_bar_base.png | Bin 0 -> 133 bytes xui/gnoll/fill_bar_left.png | Bin 0 -> 681 bytes xui/gnoll/fill_bar_middle.png | Bin 0 -> 147 bytes xui/gnoll/fill_bar_right.png | Bin 0 -> 229 bytes xui/gnoll/frame_left.png | Bin 0 -> 117 bytes xui/gnoll/frame_lower.png | Bin 0 -> 110 bytes xui/gnoll/frame_lower_left.png | Bin 0 -> 139 bytes xui/gnoll/frame_lower_right.png | Bin 0 -> 138 bytes xui/gnoll/frame_right.png | Bin 0 -> 112 bytes xui/gnoll/frame_upper.png | Bin 0 -> 109 bytes xui/gnoll/frame_upper_left.png | Bin 0 -> 134 bytes xui/gnoll/frame_upper_right.png | Bin 0 -> 133 bytes xui/gnoll/icon_frame.png | Bin 0 -> 312 bytes xui/gnoll/menu_left.png | Bin 0 -> 120 bytes xui/gnoll/menu_lower.png | Bin 0 -> 133 bytes xui/gnoll/menu_lower_left.png | Bin 0 -> 176 bytes xui/gnoll/menu_lower_right.png | Bin 0 -> 171 bytes xui/gnoll/menu_middle.png | Bin 0 -> 107 bytes xui/gnoll/menu_right.png | Bin 0 -> 119 bytes xui/gnoll/menu_upper.png | Bin 0 -> 127 bytes xui/gnoll/menu_upper_left.png | Bin 0 -> 168 bytes xui/gnoll/menu_upper_right.png | Bin 0 -> 178 bytes xui/gnoll/overicon_frame.png | Bin 0 -> 311 bytes xui/gnoll/scroll_bar_lower.png | Bin 0 -> 274 bytes xui/gnoll/scroll_bar_middle.png | Bin 0 -> 160 bytes xui/gnoll/scroll_bar_slider.png | Bin 0 -> 375 bytes xui/gnoll/scroll_bar_upper.png | Bin 0 -> 271 bytes xui/gnoll/separator_center.png | Bin 0 -> 375 bytes xui/gnoll/separator_left.png | Bin 0 -> 164 bytes xui/gnoll/separator_middle.png | Bin 0 -> 184 bytes xui/gnoll/separator_right.png | Bin 0 -> 244 bytes xui/gnoll/status_left.png | Bin 0 -> 262 bytes xui/gnoll/status_lower.png | Bin 0 -> 298 bytes xui/gnoll/status_lower_left.png | Bin 0 -> 546 bytes xui/gnoll/status_lower_right.png | Bin 0 -> 555 bytes xui/gnoll/status_middle.png | Bin 0 -> 162 bytes xui/gnoll/status_right.png | Bin 0 -> 254 bytes xui/gnoll/status_upper.png | Bin 0 -> 289 bytes xui/gnoll/status_upper_left.png | Bin 0 -> 539 bytes xui/gnoll/status_upper_right.png | Bin 0 -> 583 bytes xui/gnoll/tiny_fill_bar_base.png | Bin 0 -> 140 bytes xui/gnoll/tiny_fill_bar_left.png | Bin 0 -> 400 bytes xui/gnoll/tiny_fill_bar_middle.png | Bin 0 -> 157 bytes xui/gnoll/tiny_fill_bar_right.png | Bin 0 -> 400 bytes xui/gnoll/title_bar_left.png | Bin 0 -> 691 bytes xui/gnoll/title_bar_middle.png | Bin 0 -> 269 bytes xui/gnoll/title_bar_right.png | Bin 0 -> 482 bytes xui/gnoll/ubericon_frame.png | Bin 0 -> 221 bytes xui/gnoll/window_left.png | Bin 0 -> 405 bytes xui/gnoll/window_lower.png | Bin 0 -> 306 bytes xui/gnoll/window_lower_left.png | Bin 0 -> 1099 bytes xui/gnoll/window_lower_right.png | Bin 0 -> 1145 bytes xui/gnoll/window_right.png | Bin 0 -> 289 bytes xui/gnoll/window_upper.png | Bin 0 -> 306 bytes xui/gnoll/window_upper_left.png | Bin 0 -> 1144 bytes xui/gnoll/window_upper_right.png | Bin 0 -> 1101 bytes xui/goblin/button_left.png | Bin 0 -> 120 bytes xui/goblin/button_lower.png | Bin 0 -> 123 bytes xui/goblin/button_lower_left.png | Bin 0 -> 157 bytes xui/goblin/button_lower_right.png | Bin 0 -> 152 bytes xui/goblin/button_middle.png | Bin 0 -> 100 bytes xui/goblin/button_right.png | Bin 0 -> 119 bytes xui/goblin/button_upper.png | Bin 0 -> 120 bytes xui/goblin/button_upper_left.png | Bin 0 -> 147 bytes xui/goblin/button_upper_right.png | Bin 0 -> 155 bytes xui/goblin/check_box_off.png | Bin 0 -> 427 bytes xui/goblin/check_box_on.png | Bin 0 -> 415 bytes xui/goblin/cursor.png | Bin 0 -> 355 bytes xui/goblin/end_turn_button.png | Bin 0 -> 869 bytes xui/goblin/fill_bar_base.png | Bin 0 -> 153 bytes xui/goblin/fill_bar_left.png | Bin 0 -> 910 bytes xui/goblin/fill_bar_middle.png | Bin 0 -> 215 bytes xui/goblin/fill_bar_right.png | Bin 0 -> 334 bytes xui/goblin/frame_left.png | Bin 0 -> 114 bytes xui/goblin/frame_lower.png | Bin 0 -> 108 bytes xui/goblin/frame_lower_left.png | Bin 0 -> 142 bytes xui/goblin/frame_lower_right.png | Bin 0 -> 135 bytes xui/goblin/frame_right.png | Bin 0 -> 110 bytes xui/goblin/frame_upper.png | Bin 0 -> 107 bytes xui/goblin/frame_upper_left.png | Bin 0 -> 137 bytes xui/goblin/frame_upper_right.png | Bin 0 -> 134 bytes xui/goblin/icon_frame.png | Bin 0 -> 250 bytes xui/goblin/menu_left.png | Bin 0 -> 120 bytes xui/goblin/menu_lower.png | Bin 0 -> 122 bytes xui/goblin/menu_lower_left.png | Bin 0 -> 176 bytes xui/goblin/menu_lower_right.png | Bin 0 -> 180 bytes xui/goblin/menu_middle.png | Bin 0 -> 100 bytes xui/goblin/menu_right.png | Bin 0 -> 119 bytes xui/goblin/menu_upper.png | Bin 0 -> 119 bytes xui/goblin/menu_upper_left.png | Bin 0 -> 165 bytes xui/goblin/menu_upper_right.png | Bin 0 -> 184 bytes xui/goblin/overicon_frame.png | Bin 0 -> 252 bytes xui/goblin/scroll_bar_lower.png | Bin 0 -> 280 bytes xui/goblin/scroll_bar_middle.png | Bin 0 -> 162 bytes xui/goblin/scroll_bar_slider.png | Bin 0 -> 415 bytes xui/goblin/scroll_bar_upper.png | Bin 0 -> 277 bytes xui/goblin/separator_center.png | Bin 0 -> 415 bytes xui/goblin/separator_left.png | Bin 0 -> 194 bytes xui/goblin/separator_middle.png | Bin 0 -> 123 bytes xui/goblin/separator_right.png | Bin 0 -> 209 bytes xui/goblin/status_left.png | Bin 0 -> 259 bytes xui/goblin/status_lower.png | Bin 0 -> 259 bytes xui/goblin/status_lower_left.png | Bin 0 -> 414 bytes xui/goblin/status_lower_right.png | Bin 0 -> 402 bytes xui/goblin/status_middle.png | Bin 0 -> 125 bytes xui/goblin/status_right.png | Bin 0 -> 247 bytes xui/goblin/status_upper.png | Bin 0 -> 254 bytes xui/goblin/status_upper_left.png | Bin 0 -> 377 bytes xui/goblin/status_upper_right.png | Bin 0 -> 476 bytes xui/goblin/tiny_fill_bar_base.png | Bin 0 -> 156 bytes xui/goblin/tiny_fill_bar_left.png | Bin 0 -> 502 bytes xui/goblin/tiny_fill_bar_middle.png | Bin 0 -> 246 bytes xui/goblin/tiny_fill_bar_right.png | Bin 0 -> 341 bytes xui/goblin/title_bar_left.png | Bin 0 -> 895 bytes xui/goblin/title_bar_middle.png | Bin 0 -> 213 bytes xui/goblin/title_bar_right.png | Bin 0 -> 476 bytes xui/goblin/ubericon_frame.png | Bin 0 -> 184 bytes xui/goblin/window_left.png | Bin 0 -> 253 bytes xui/goblin/window_lower.png | Bin 0 -> 244 bytes xui/goblin/window_lower_left.png | Bin 0 -> 1160 bytes xui/goblin/window_lower_right.png | Bin 0 -> 1130 bytes xui/goblin/window_right.png | Bin 0 -> 242 bytes xui/goblin/window_upper.png | Bin 0 -> 237 bytes xui/goblin/window_upper_left.png | Bin 0 -> 1117 bytes xui/goblin/window_upper_right.png | Bin 0 -> 1174 bytes xui/imp/button_left.png | Bin 0 -> 118 bytes xui/imp/button_lower.png | Bin 0 -> 115 bytes xui/imp/button_lower_left.png | Bin 0 -> 128 bytes xui/imp/button_lower_right.png | Bin 0 -> 139 bytes xui/imp/button_middle.png | Bin 0 -> 95 bytes xui/imp/button_right.png | Bin 0 -> 118 bytes xui/imp/button_upper.png | Bin 0 -> 116 bytes xui/imp/button_upper_left.png | Bin 0 -> 128 bytes xui/imp/button_upper_right.png | Bin 0 -> 128 bytes xui/imp/check_box_off.png | Bin 0 -> 477 bytes xui/imp/check_box_on.png | Bin 0 -> 490 bytes xui/imp/cursor.png | Bin 0 -> 380 bytes xui/imp/end_turn_button.png | Bin 0 -> 1066 bytes xui/imp/fill_bar_base.png | Bin 0 -> 133 bytes xui/imp/fill_bar_left.png | Bin 0 -> 1009 bytes xui/imp/fill_bar_middle.png | Bin 0 -> 137 bytes xui/imp/fill_bar_right.png | Bin 0 -> 239 bytes xui/imp/frame_left.png | Bin 0 -> 112 bytes xui/imp/frame_lower.png | Bin 0 -> 110 bytes xui/imp/frame_lower_left.png | Bin 0 -> 135 bytes xui/imp/frame_lower_right.png | Bin 0 -> 131 bytes xui/imp/frame_right.png | Bin 0 -> 109 bytes xui/imp/frame_upper.png | Bin 0 -> 112 bytes xui/imp/frame_upper_left.png | Bin 0 -> 126 bytes xui/imp/frame_upper_right.png | Bin 0 -> 139 bytes xui/imp/icon_frame.png | Bin 0 -> 202 bytes xui/imp/menu_left.png | Bin 0 -> 105 bytes xui/imp/menu_lower.png | Bin 0 -> 115 bytes xui/imp/menu_lower_left.png | Bin 0 -> 128 bytes xui/imp/menu_lower_right.png | Bin 0 -> 139 bytes xui/imp/menu_middle.png | Bin 0 -> 95 bytes xui/imp/menu_right.png | Bin 0 -> 106 bytes xui/imp/menu_upper.png | Bin 0 -> 116 bytes xui/imp/menu_upper_left.png | Bin 0 -> 128 bytes xui/imp/menu_upper_right.png | Bin 0 -> 128 bytes xui/imp/overicon_frame.png | Bin 0 -> 187 bytes xui/imp/scroll_bar_lower.png | Bin 0 -> 257 bytes xui/imp/scroll_bar_middle.png | Bin 0 -> 170 bytes xui/imp/scroll_bar_slider.png | Bin 0 -> 465 bytes xui/imp/scroll_bar_upper.png | Bin 0 -> 252 bytes xui/imp/separator_center.png | Bin 0 -> 465 bytes xui/imp/separator_left.png | Bin 0 -> 217 bytes xui/imp/separator_middle.png | Bin 0 -> 130 bytes xui/imp/separator_right.png | Bin 0 -> 144 bytes xui/imp/status_left.png | Bin 0 -> 170 bytes xui/imp/status_lower.png | Bin 0 -> 197 bytes xui/imp/status_lower_left.png | Bin 0 -> 597 bytes xui/imp/status_lower_right.png | Bin 0 -> 552 bytes xui/imp/status_middle.png | Bin 0 -> 119 bytes xui/imp/status_right.png | Bin 0 -> 170 bytes xui/imp/status_upper.png | Bin 0 -> 197 bytes xui/imp/status_upper_left.png | Bin 0 -> 546 bytes xui/imp/status_upper_right.png | Bin 0 -> 599 bytes xui/imp/tiny_fill_bar_base.png | Bin 0 -> 138 bytes xui/imp/tiny_fill_bar_left.png | Bin 0 -> 454 bytes xui/imp/tiny_fill_bar_middle.png | Bin 0 -> 153 bytes xui/imp/tiny_fill_bar_right.png | Bin 0 -> 296 bytes xui/imp/title_bar_left.png | Bin 0 -> 718 bytes xui/imp/title_bar_middle.png | Bin 0 -> 151 bytes xui/imp/title_bar_right.png | Bin 0 -> 210 bytes xui/imp/ubericon_frame.png | Bin 0 -> 171 bytes xui/imp/window_left.png | Bin 0 -> 237 bytes xui/imp/window_lower.png | Bin 0 -> 236 bytes xui/imp/window_lower_left.png | Bin 0 -> 1114 bytes xui/imp/window_lower_right.png | Bin 0 -> 1201 bytes xui/imp/window_right.png | Bin 0 -> 237 bytes xui/imp/window_upper.png | Bin 0 -> 291 bytes xui/imp/window_upper_left.png | Bin 0 -> 1136 bytes xui/imp/window_upper_right.png | Bin 0 -> 1318 bytes xui/kobold/button_left.png | Bin 0 -> 119 bytes xui/kobold/button_lower.png | Bin 0 -> 122 bytes xui/kobold/button_lower_left.png | Bin 0 -> 156 bytes xui/kobold/button_lower_right.png | Bin 0 -> 154 bytes xui/kobold/button_middle.png | Bin 0 -> 100 bytes xui/kobold/button_right.png | Bin 0 -> 116 bytes xui/kobold/button_upper.png | Bin 0 -> 121 bytes xui/kobold/button_upper_left.png | Bin 0 -> 144 bytes xui/kobold/button_upper_right.png | Bin 0 -> 143 bytes xui/kobold/check_box_off.png | Bin 0 -> 329 bytes xui/kobold/check_box_on.png | Bin 0 -> 409 bytes xui/kobold/cursor.png | Bin 0 -> 391 bytes xui/kobold/end_turn_button.png | Bin 0 -> 1375 bytes xui/kobold/fill_bar_base.png | Bin 0 -> 167 bytes xui/kobold/fill_bar_left.png | Bin 0 -> 1685 bytes xui/kobold/fill_bar_middle.png | Bin 0 -> 171 bytes xui/kobold/fill_bar_right.png | Bin 0 -> 590 bytes xui/kobold/frame_left.png | Bin 0 -> 116 bytes xui/kobold/frame_lower.png | Bin 0 -> 107 bytes xui/kobold/frame_lower_left.png | Bin 0 -> 150 bytes xui/kobold/frame_lower_right.png | Bin 0 -> 144 bytes xui/kobold/frame_right.png | Bin 0 -> 112 bytes xui/kobold/frame_upper.png | Bin 0 -> 110 bytes xui/kobold/frame_upper_left.png | Bin 0 -> 141 bytes xui/kobold/frame_upper_right.png | Bin 0 -> 154 bytes xui/kobold/icon_frame.png | Bin 0 -> 234 bytes xui/kobold/menu_left.png | Bin 0 -> 124 bytes xui/kobold/menu_lower.png | Bin 0 -> 133 bytes xui/kobold/menu_lower_left.png | Bin 0 -> 208 bytes xui/kobold/menu_lower_right.png | Bin 0 -> 185 bytes xui/kobold/menu_middle.png | Bin 0 -> 99 bytes xui/kobold/menu_right.png | Bin 0 -> 125 bytes xui/kobold/menu_upper.png | Bin 0 -> 130 bytes xui/kobold/menu_upper_left.png | Bin 0 -> 174 bytes xui/kobold/menu_upper_right.png | Bin 0 -> 235 bytes xui/kobold/overicon_frame.png | Bin 0 -> 217 bytes xui/kobold/scroll_bar_lower.png | Bin 0 -> 318 bytes xui/kobold/scroll_bar_middle.png | Bin 0 -> 159 bytes xui/kobold/scroll_bar_slider.png | Bin 0 -> 329 bytes xui/kobold/scroll_bar_upper.png | Bin 0 -> 313 bytes xui/kobold/separator_center.png | Bin 0 -> 329 bytes xui/kobold/separator_left.png | Bin 0 -> 229 bytes xui/kobold/separator_middle.png | Bin 0 -> 153 bytes xui/kobold/separator_right.png | Bin 0 -> 272 bytes xui/kobold/status_left.png | Bin 0 -> 186 bytes xui/kobold/status_lower.png | Bin 0 -> 185 bytes xui/kobold/status_lower_left.png | Bin 0 -> 596 bytes xui/kobold/status_lower_right.png | Bin 0 -> 602 bytes xui/kobold/status_middle.png | Bin 0 -> 182 bytes xui/kobold/status_right.png | Bin 0 -> 177 bytes xui/kobold/status_upper.png | Bin 0 -> 192 bytes xui/kobold/status_upper_left.png | Bin 0 -> 602 bytes xui/kobold/status_upper_right.png | Bin 0 -> 743 bytes xui/kobold/tiny_fill_bar_base.png | Bin 0 -> 170 bytes xui/kobold/tiny_fill_bar_left.png | Bin 0 -> 613 bytes xui/kobold/tiny_fill_bar_middle.png | Bin 0 -> 176 bytes xui/kobold/tiny_fill_bar_right.png | Bin 0 -> 507 bytes xui/kobold/title_bar_left.png | Bin 0 -> 965 bytes xui/kobold/title_bar_middle.png | Bin 0 -> 211 bytes xui/kobold/title_bar_right.png | Bin 0 -> 646 bytes xui/kobold/ubericon_frame.png | Bin 0 -> 192 bytes xui/kobold/window_left.png | Bin 0 -> 311 bytes xui/kobold/window_lower.png | Bin 0 -> 557 bytes xui/kobold/window_lower_left.png | Bin 0 -> 1792 bytes xui/kobold/window_lower_right.png | Bin 0 -> 2535 bytes xui/kobold/window_right.png | Bin 0 -> 320 bytes xui/kobold/window_upper.png | Bin 0 -> 288 bytes xui/kobold/window_upper_left.png | Bin 0 -> 662 bytes xui/kobold/window_upper_right.png | Bin 0 -> 661 bytes xui/main/button_left.png | Bin 0 -> 113 bytes xui/main/button_lower.png | Bin 0 -> 119 bytes xui/main/button_lower_left.png | Bin 0 -> 132 bytes xui/main/button_lower_right.png | Bin 0 -> 133 bytes xui/main/button_middle.png | Bin 0 -> 100 bytes xui/main/button_right.png | Bin 0 -> 113 bytes xui/main/button_upper.png | Bin 0 -> 117 bytes xui/main/button_upper_left.png | Bin 0 -> 125 bytes xui/main/button_upper_right.png | Bin 0 -> 133 bytes xui/main/check_box_off.png | Bin 0 -> 353 bytes xui/main/check_box_on.png | Bin 0 -> 348 bytes xui/main/cursor.png | Bin 0 -> 242 bytes xui/main/end_turn_button.png | Bin 0 -> 729 bytes xui/main/fill_bar_base.png | Bin 0 -> 126 bytes xui/main/fill_bar_left.png | Bin 0 -> 413 bytes xui/main/fill_bar_middle.png | Bin 0 -> 136 bytes xui/main/fill_bar_right.png | Bin 0 -> 179 bytes xui/main/frame_left.png | Bin 0 -> 105 bytes xui/main/frame_lower.png | Bin 0 -> 107 bytes xui/main/frame_lower_left.png | Bin 0 -> 125 bytes xui/main/frame_lower_right.png | Bin 0 -> 116 bytes xui/main/frame_right.png | Bin 0 -> 103 bytes xui/main/frame_upper.png | Bin 0 -> 106 bytes xui/main/frame_upper_left.png | Bin 0 -> 122 bytes xui/main/frame_upper_right.png | Bin 0 -> 126 bytes xui/main/icon_frame.png | Bin 0 -> 169 bytes xui/main/menu_left.png | Bin 0 -> 121 bytes xui/main/menu_lower.png | Bin 0 -> 127 bytes xui/main/menu_lower_left.png | Bin 0 -> 138 bytes xui/main/menu_lower_right.png | Bin 0 -> 138 bytes xui/main/menu_middle.png | Bin 0 -> 107 bytes xui/main/menu_right.png | Bin 0 -> 117 bytes xui/main/menu_upper.png | Bin 0 -> 127 bytes xui/main/menu_upper_left.png | Bin 0 -> 135 bytes xui/main/menu_upper_right.png | Bin 0 -> 139 bytes xui/main/overicon_frame.png | Bin 0 -> 168 bytes xui/main/scroll_bar_lower.png | Bin 0 -> 190 bytes xui/main/scroll_bar_middle.png | Bin 0 -> 132 bytes xui/main/scroll_bar_slider.png | Bin 0 -> 353 bytes xui/main/scroll_bar_upper.png | Bin 0 -> 192 bytes xui/main/separator_center.png | Bin 0 -> 353 bytes xui/main/separator_left.png | Bin 0 -> 121 bytes xui/main/separator_middle.png | Bin 0 -> 120 bytes xui/main/separator_right.png | Bin 0 -> 132 bytes xui/main/status_left.png | Bin 0 -> 132 bytes xui/main/status_lower.png | Bin 0 -> 126 bytes xui/main/status_lower_left.png | Bin 0 -> 401 bytes xui/main/status_lower_right.png | Bin 0 -> 412 bytes xui/main/status_middle.png | Bin 0 -> 122 bytes xui/main/status_right.png | Bin 0 -> 132 bytes xui/main/status_upper.png | Bin 0 -> 126 bytes xui/main/status_upper_left.png | Bin 0 -> 392 bytes xui/main/status_upper_right.png | Bin 0 -> 428 bytes xui/main/tiny_fill_bar_base.png | Bin 0 -> 128 bytes xui/main/tiny_fill_bar_left.png | Bin 0 -> 382 bytes xui/main/tiny_fill_bar_middle.png | Bin 0 -> 143 bytes xui/main/tiny_fill_bar_right.png | Bin 0 -> 254 bytes xui/main/title_bar_left.png | Bin 0 -> 718 bytes xui/main/title_bar_middle.png | Bin 0 -> 143 bytes xui/main/title_bar_right.png | Bin 0 -> 225 bytes xui/main/ubericon_frame.png | Bin 0 -> 147 bytes xui/main/window_left.png | Bin 0 -> 170 bytes xui/main/window_lower.png | Bin 0 -> 184 bytes xui/main/window_lower_left.png | Bin 0 -> 793 bytes xui/main/window_lower_right.png | Bin 0 -> 796 bytes xui/main/window_right.png | Bin 0 -> 172 bytes xui/main/window_upper.png | Bin 0 -> 178 bytes xui/main/window_upper_left.png | Bin 0 -> 748 bytes xui/main/window_upper_right.png | Bin 0 -> 816 bytes xui/map_preview_panel_off.png | Bin 0 -> 200 bytes xui/map_preview_panel_on.png | Bin 0 -> 202 bytes xui/monospace.png | Bin 0 -> 6376 bytes xui/palette.png | Bin 0 -> 210 bytes xui/regular.png | Bin 0 -> 9327 bytes xui/status_preview_panel_off.png | Bin 0 -> 209 bytes xui/status_preview_panel_on.png | Bin 0 -> 211 bytes xui/text_box_panel_off.png | Bin 0 -> 178 bytes xui/text_box_panel_on.png | Bin 0 -> 180 bytes xulkan.h | 2351 +++++++++++++++++++++++ xungeon.h | 271 +++ xuxuxu.c | 130 ++ xyntax.h | 175 ++ 596 files changed, 15958 insertions(+) create mode 100755 .gitignore create mode 100755 LICENSE create mode 100755 README.md create mode 100755 compile.sh create mode 100755 install.sh create mode 100755 test create mode 100644 test.c create mode 100755 xachine.h create mode 100755 xanguage.h create mode 100755 xanguage/ada.h create mode 100755 xanguage/bash.h create mode 100755 xanguage/c++.h create mode 100755 xanguage/c.h create mode 100755 xanguage/common.h create mode 100755 xanguage/d.h create mode 100755 xanguage/eaxhla.h create mode 100755 xanguage/flat.h create mode 100755 xanguage/fortran.h create mode 100755 xanguage/go.h create mode 100755 xanguage/haskell.h create mode 100755 xanguage/lua.h create mode 100755 xanguage/pascal.h create mode 100755 xanguage/python.h create mode 100755 xanguage/valgrind.h create mode 100755 xanual/adc.md create mode 100755 xanual/add.md create mode 100755 xanual/and.md create mode 100755 xanual/call.md create mode 100755 xanual/cmovcc.md create mode 100755 xanual/cmp.md create mode 100755 xanual/dec.md create mode 100755 xanual/div.md create mode 100755 xanual/enter.md create mode 100755 xanual/idiv.md create mode 100755 xanual/imul.md create mode 100755 xanual/inc.md create mode 100755 xanual/jcc.md create mode 100755 xanual/jmp.md create mode 100755 xanual/leave.md create mode 100755 xanual/mov.md create mode 100755 xanual/mul.md create mode 100755 xanual/neg.md create mode 100755 xanual/nop.md create mode 100755 xanual/not.md create mode 100755 xanual/or.md create mode 100755 xanual/pop.md create mode 100755 xanual/push.md create mode 100755 xanual/ret.md create mode 100755 xanual/rot.md create mode 100755 xanual/sbb.md create mode 100755 xanual/setcc.md create mode 100755 xanual/sft.md create mode 100755 xanual/sub.md create mode 100755 xanual/syscall.md create mode 100755 xanual/sysenter.md create mode 100755 xanual/sysexit.md create mode 100755 xanual/sysret.md create mode 100755 xanual/template.md create mode 100755 xanual/xor.md create mode 100755 xaptor create mode 100644 xaptor.c create mode 100644 xaptor.h create mode 100755 xarbon.c create mode 100644 xarticle.h create mode 100644 xatrix.h create mode 100755 xcript.h create mode 100755 xector.h create mode 100755 xhallenge.c create mode 100755 xhallenge_list.cfg create mode 100755 xiasma.h create mode 100755 xighlight.c create mode 100755 xogueout create mode 100644 xogueout.c create mode 100755 xommon.h create mode 100755 xop.c create mode 100644 xormat.h create mode 100644 xormat/jxl.h create mode 100644 xormat/png.h create mode 100755 xpenal.h create mode 100755 xpengl.h create mode 100755 xphere.h create mode 100755 xprite.h create mode 100755 xrocessor.h create mode 100755 xross.h create mode 100755 xscii.c create mode 100755 xtandard.h create mode 100755 xui.h create mode 100755 xui/common/fullscreen_off.png create mode 100755 xui/common/fullscreen_on.png create mode 100755 xui/common/map_preview_panel_off.png create mode 100755 xui/common/map_preview_panel_on.png create mode 100755 xui/common/monospace.png create mode 100755 xui/common/palette.png create mode 100755 xui/common/regular.png create mode 100755 xui/common/status_preview_panel_off.png create mode 100755 xui/common/status_preview_panel_on.png create mode 100755 xui/common/text_box_panel_off.png create mode 100755 xui/common/text_box_panel_on.png create mode 100755 xui/dwarf/button_left.png create mode 100755 xui/dwarf/button_lower.png create mode 100755 xui/dwarf/button_lower_left.png create mode 100755 xui/dwarf/button_lower_right.png create mode 100755 xui/dwarf/button_middle.png create mode 100755 xui/dwarf/button_right.png create mode 100755 xui/dwarf/button_upper.png create mode 100755 xui/dwarf/button_upper_left.png create mode 100755 xui/dwarf/button_upper_right.png create mode 100755 xui/dwarf/check_box_off.png create mode 100755 xui/dwarf/check_box_on.png create mode 100755 xui/dwarf/cursor.png create mode 100755 xui/dwarf/end_turn_button.png create mode 100755 xui/dwarf/fill_bar_base.png create mode 100755 xui/dwarf/fill_bar_left.png create mode 100755 xui/dwarf/fill_bar_middle.png create mode 100755 xui/dwarf/fill_bar_right.png create mode 100755 xui/dwarf/frame_left.png create mode 100755 xui/dwarf/frame_lower.png create mode 100755 xui/dwarf/frame_lower_left.png create mode 100755 xui/dwarf/frame_lower_right.png create mode 100755 xui/dwarf/frame_right.png create mode 100755 xui/dwarf/frame_upper.png create mode 100755 xui/dwarf/frame_upper_left.png create mode 100755 xui/dwarf/frame_upper_right.png create mode 100755 xui/dwarf/icon_frame.png create mode 100755 xui/dwarf/menu_left.png create mode 100755 xui/dwarf/menu_lower.png create mode 100755 xui/dwarf/menu_lower_left.png create mode 100755 xui/dwarf/menu_lower_right.png create mode 100755 xui/dwarf/menu_middle.png create mode 100755 xui/dwarf/menu_right.png create mode 100755 xui/dwarf/menu_upper.png create mode 100755 xui/dwarf/menu_upper_left.png create mode 100755 xui/dwarf/menu_upper_right.png create mode 100755 xui/dwarf/overicon_frame.png create mode 100755 xui/dwarf/scroll_bar_lower.png create mode 100755 xui/dwarf/scroll_bar_middle.png create mode 100755 xui/dwarf/scroll_bar_slider.png create mode 100755 xui/dwarf/scroll_bar_upper.png create mode 100755 xui/dwarf/separator_center.png create mode 100755 xui/dwarf/separator_left.png create mode 100755 xui/dwarf/separator_middle.png create mode 100755 xui/dwarf/separator_right.png create mode 100755 xui/dwarf/status_left.png create mode 100755 xui/dwarf/status_lower.png create mode 100755 xui/dwarf/status_lower_left.png create mode 100755 xui/dwarf/status_lower_right.png create mode 100755 xui/dwarf/status_middle.png create mode 100755 xui/dwarf/status_right.png create mode 100755 xui/dwarf/status_upper.png create mode 100755 xui/dwarf/status_upper_left.png create mode 100755 xui/dwarf/status_upper_right.png create mode 100755 xui/dwarf/tiny_fill_bar_base.png create mode 100755 xui/dwarf/tiny_fill_bar_left.png create mode 100755 xui/dwarf/tiny_fill_bar_middle.png create mode 100755 xui/dwarf/tiny_fill_bar_right.png create mode 100755 xui/dwarf/title_bar_left.png create mode 100755 xui/dwarf/title_bar_middle.png create mode 100755 xui/dwarf/title_bar_right.png create mode 100755 xui/dwarf/ubericon_frame.png create mode 100755 xui/dwarf/window_left.png create mode 100755 xui/dwarf/window_lower.png create mode 100755 xui/dwarf/window_lower_left.png create mode 100755 xui/dwarf/window_lower_right.png create mode 100755 xui/dwarf/window_right.png create mode 100755 xui/dwarf/window_upper.png create mode 100755 xui/dwarf/window_upper_left.png create mode 100755 xui/dwarf/window_upper_right.png create mode 100755 xui/fairy/button_left.png create mode 100755 xui/fairy/button_lower.png create mode 100755 xui/fairy/button_lower_left.png create mode 100755 xui/fairy/button_lower_right.png create mode 100755 xui/fairy/button_middle.png create mode 100755 xui/fairy/button_right.png create mode 100755 xui/fairy/button_upper.png create mode 100755 xui/fairy/button_upper_left.png create mode 100755 xui/fairy/button_upper_right.png create mode 100755 xui/fairy/check_box_off.png create mode 100755 xui/fairy/check_box_on.png create mode 100755 xui/fairy/cursor.png create mode 100755 xui/fairy/end_turn_button.png create mode 100755 xui/fairy/fill_bar_base.png create mode 100755 xui/fairy/fill_bar_left.png create mode 100755 xui/fairy/fill_bar_middle.png create mode 100755 xui/fairy/fill_bar_right.png create mode 100755 xui/fairy/frame_left.png create mode 100755 xui/fairy/frame_lower.png create mode 100755 xui/fairy/frame_lower_left.png create mode 100755 xui/fairy/frame_lower_right.png create mode 100755 xui/fairy/frame_right.png create mode 100755 xui/fairy/frame_upper.png create mode 100755 xui/fairy/frame_upper_left.png create mode 100755 xui/fairy/frame_upper_right.png create mode 100755 xui/fairy/icon_frame.png create mode 100755 xui/fairy/menu_left.png create mode 100755 xui/fairy/menu_lower.png create mode 100755 xui/fairy/menu_lower_left.png create mode 100755 xui/fairy/menu_lower_right.png create mode 100755 xui/fairy/menu_middle.png create mode 100755 xui/fairy/menu_right.png create mode 100755 xui/fairy/menu_upper.png create mode 100755 xui/fairy/menu_upper_left.png create mode 100755 xui/fairy/menu_upper_right.png create mode 100755 xui/fairy/overicon_frame.png create mode 100755 xui/fairy/scroll_bar_lower.png create mode 100755 xui/fairy/scroll_bar_middle.png create mode 100644 xui/fairy/scroll_bar_slider.png create mode 100755 xui/fairy/scroll_bar_upper.png create mode 100644 xui/fairy/separator_center.png create mode 100755 xui/fairy/separator_left.png create mode 100755 xui/fairy/separator_middle.png create mode 100755 xui/fairy/separator_right.png create mode 100755 xui/fairy/status_left.png create mode 100755 xui/fairy/status_lower.png create mode 100755 xui/fairy/status_lower_left.png create mode 100755 xui/fairy/status_lower_right.png create mode 100755 xui/fairy/status_middle.png create mode 100755 xui/fairy/status_right.png create mode 100755 xui/fairy/status_upper.png create mode 100755 xui/fairy/status_upper_left.png create mode 100755 xui/fairy/status_upper_right.png create mode 100755 xui/fairy/tiny_fill_bar_base.png create mode 100755 xui/fairy/tiny_fill_bar_left.png create mode 100755 xui/fairy/tiny_fill_bar_middle.png create mode 100755 xui/fairy/tiny_fill_bar_right.png create mode 100755 xui/fairy/title_bar_left.png create mode 100755 xui/fairy/title_bar_middle.png create mode 100755 xui/fairy/title_bar_right.png create mode 100755 xui/fairy/ubericon_frame.png create mode 100755 xui/fairy/window_left.png create mode 100755 xui/fairy/window_lower.png create mode 100755 xui/fairy/window_lower_left.png create mode 100755 xui/fairy/window_lower_right.png create mode 100755 xui/fairy/window_right.png create mode 100755 xui/fairy/window_upper.png create mode 100755 xui/fairy/window_upper_left.png create mode 100755 xui/fairy/window_upper_right.png create mode 100755 xui/fullscreen_off.png create mode 100755 xui/fullscreen_on.png create mode 100755 xui/gnoll/button_left.png create mode 100755 xui/gnoll/button_lower.png create mode 100755 xui/gnoll/button_lower_left.png create mode 100755 xui/gnoll/button_lower_right.png create mode 100755 xui/gnoll/button_middle.png create mode 100755 xui/gnoll/button_right.png create mode 100755 xui/gnoll/button_upper.png create mode 100755 xui/gnoll/button_upper_left.png create mode 100755 xui/gnoll/button_upper_right.png create mode 100755 xui/gnoll/check_box_off.png create mode 100755 xui/gnoll/check_box_on.png create mode 100755 xui/gnoll/cursor.png create mode 100755 xui/gnoll/end_turn_button.png create mode 100755 xui/gnoll/fill_bar_base.png create mode 100755 xui/gnoll/fill_bar_left.png create mode 100755 xui/gnoll/fill_bar_middle.png create mode 100755 xui/gnoll/fill_bar_right.png create mode 100755 xui/gnoll/frame_left.png create mode 100755 xui/gnoll/frame_lower.png create mode 100755 xui/gnoll/frame_lower_left.png create mode 100755 xui/gnoll/frame_lower_right.png create mode 100755 xui/gnoll/frame_right.png create mode 100755 xui/gnoll/frame_upper.png create mode 100755 xui/gnoll/frame_upper_left.png create mode 100755 xui/gnoll/frame_upper_right.png create mode 100755 xui/gnoll/icon_frame.png create mode 100755 xui/gnoll/menu_left.png create mode 100755 xui/gnoll/menu_lower.png create mode 100755 xui/gnoll/menu_lower_left.png create mode 100755 xui/gnoll/menu_lower_right.png create mode 100755 xui/gnoll/menu_middle.png create mode 100755 xui/gnoll/menu_right.png create mode 100755 xui/gnoll/menu_upper.png create mode 100755 xui/gnoll/menu_upper_left.png create mode 100755 xui/gnoll/menu_upper_right.png create mode 100755 xui/gnoll/overicon_frame.png create mode 100755 xui/gnoll/scroll_bar_lower.png create mode 100755 xui/gnoll/scroll_bar_middle.png create mode 100755 xui/gnoll/scroll_bar_slider.png create mode 100755 xui/gnoll/scroll_bar_upper.png create mode 100755 xui/gnoll/separator_center.png create mode 100755 xui/gnoll/separator_left.png create mode 100755 xui/gnoll/separator_middle.png create mode 100755 xui/gnoll/separator_right.png create mode 100755 xui/gnoll/status_left.png create mode 100755 xui/gnoll/status_lower.png create mode 100755 xui/gnoll/status_lower_left.png create mode 100755 xui/gnoll/status_lower_right.png create mode 100755 xui/gnoll/status_middle.png create mode 100755 xui/gnoll/status_right.png create mode 100755 xui/gnoll/status_upper.png create mode 100755 xui/gnoll/status_upper_left.png create mode 100755 xui/gnoll/status_upper_right.png create mode 100755 xui/gnoll/tiny_fill_bar_base.png create mode 100755 xui/gnoll/tiny_fill_bar_left.png create mode 100755 xui/gnoll/tiny_fill_bar_middle.png create mode 100755 xui/gnoll/tiny_fill_bar_right.png create mode 100755 xui/gnoll/title_bar_left.png create mode 100755 xui/gnoll/title_bar_middle.png create mode 100755 xui/gnoll/title_bar_right.png create mode 100755 xui/gnoll/ubericon_frame.png create mode 100755 xui/gnoll/window_left.png create mode 100755 xui/gnoll/window_lower.png create mode 100755 xui/gnoll/window_lower_left.png create mode 100755 xui/gnoll/window_lower_right.png create mode 100755 xui/gnoll/window_right.png create mode 100755 xui/gnoll/window_upper.png create mode 100755 xui/gnoll/window_upper_left.png create mode 100755 xui/gnoll/window_upper_right.png create mode 100755 xui/goblin/button_left.png create mode 100755 xui/goblin/button_lower.png create mode 100755 xui/goblin/button_lower_left.png create mode 100755 xui/goblin/button_lower_right.png create mode 100755 xui/goblin/button_middle.png create mode 100755 xui/goblin/button_right.png create mode 100755 xui/goblin/button_upper.png create mode 100755 xui/goblin/button_upper_left.png create mode 100755 xui/goblin/button_upper_right.png create mode 100755 xui/goblin/check_box_off.png create mode 100755 xui/goblin/check_box_on.png create mode 100755 xui/goblin/cursor.png create mode 100755 xui/goblin/end_turn_button.png create mode 100755 xui/goblin/fill_bar_base.png create mode 100755 xui/goblin/fill_bar_left.png create mode 100755 xui/goblin/fill_bar_middle.png create mode 100755 xui/goblin/fill_bar_right.png create mode 100755 xui/goblin/frame_left.png create mode 100755 xui/goblin/frame_lower.png create mode 100755 xui/goblin/frame_lower_left.png create mode 100755 xui/goblin/frame_lower_right.png create mode 100755 xui/goblin/frame_right.png create mode 100755 xui/goblin/frame_upper.png create mode 100755 xui/goblin/frame_upper_left.png create mode 100755 xui/goblin/frame_upper_right.png create mode 100755 xui/goblin/icon_frame.png create mode 100755 xui/goblin/menu_left.png create mode 100755 xui/goblin/menu_lower.png create mode 100755 xui/goblin/menu_lower_left.png create mode 100755 xui/goblin/menu_lower_right.png create mode 100755 xui/goblin/menu_middle.png create mode 100755 xui/goblin/menu_right.png create mode 100755 xui/goblin/menu_upper.png create mode 100755 xui/goblin/menu_upper_left.png create mode 100755 xui/goblin/menu_upper_right.png create mode 100755 xui/goblin/overicon_frame.png create mode 100755 xui/goblin/scroll_bar_lower.png create mode 100755 xui/goblin/scroll_bar_middle.png create mode 100755 xui/goblin/scroll_bar_slider.png create mode 100755 xui/goblin/scroll_bar_upper.png create mode 100755 xui/goblin/separator_center.png create mode 100755 xui/goblin/separator_left.png create mode 100755 xui/goblin/separator_middle.png create mode 100755 xui/goblin/separator_right.png create mode 100755 xui/goblin/status_left.png create mode 100755 xui/goblin/status_lower.png create mode 100755 xui/goblin/status_lower_left.png create mode 100755 xui/goblin/status_lower_right.png create mode 100755 xui/goblin/status_middle.png create mode 100755 xui/goblin/status_right.png create mode 100755 xui/goblin/status_upper.png create mode 100755 xui/goblin/status_upper_left.png create mode 100755 xui/goblin/status_upper_right.png create mode 100755 xui/goblin/tiny_fill_bar_base.png create mode 100755 xui/goblin/tiny_fill_bar_left.png create mode 100755 xui/goblin/tiny_fill_bar_middle.png create mode 100755 xui/goblin/tiny_fill_bar_right.png create mode 100755 xui/goblin/title_bar_left.png create mode 100755 xui/goblin/title_bar_middle.png create mode 100755 xui/goblin/title_bar_right.png create mode 100755 xui/goblin/ubericon_frame.png create mode 100755 xui/goblin/window_left.png create mode 100755 xui/goblin/window_lower.png create mode 100755 xui/goblin/window_lower_left.png create mode 100755 xui/goblin/window_lower_right.png create mode 100755 xui/goblin/window_right.png create mode 100755 xui/goblin/window_upper.png create mode 100755 xui/goblin/window_upper_left.png create mode 100755 xui/goblin/window_upper_right.png create mode 100755 xui/imp/button_left.png create mode 100755 xui/imp/button_lower.png create mode 100755 xui/imp/button_lower_left.png create mode 100755 xui/imp/button_lower_right.png create mode 100755 xui/imp/button_middle.png create mode 100755 xui/imp/button_right.png create mode 100755 xui/imp/button_upper.png create mode 100755 xui/imp/button_upper_left.png create mode 100755 xui/imp/button_upper_right.png create mode 100755 xui/imp/check_box_off.png create mode 100755 xui/imp/check_box_on.png create mode 100755 xui/imp/cursor.png create mode 100755 xui/imp/end_turn_button.png create mode 100755 xui/imp/fill_bar_base.png create mode 100755 xui/imp/fill_bar_left.png create mode 100755 xui/imp/fill_bar_middle.png create mode 100755 xui/imp/fill_bar_right.png create mode 100755 xui/imp/frame_left.png create mode 100755 xui/imp/frame_lower.png create mode 100755 xui/imp/frame_lower_left.png create mode 100755 xui/imp/frame_lower_right.png create mode 100755 xui/imp/frame_right.png create mode 100755 xui/imp/frame_upper.png create mode 100755 xui/imp/frame_upper_left.png create mode 100755 xui/imp/frame_upper_right.png create mode 100755 xui/imp/icon_frame.png create mode 100755 xui/imp/menu_left.png create mode 100755 xui/imp/menu_lower.png create mode 100755 xui/imp/menu_lower_left.png create mode 100755 xui/imp/menu_lower_right.png create mode 100755 xui/imp/menu_middle.png create mode 100755 xui/imp/menu_right.png create mode 100755 xui/imp/menu_upper.png create mode 100755 xui/imp/menu_upper_left.png create mode 100755 xui/imp/menu_upper_right.png create mode 100755 xui/imp/overicon_frame.png create mode 100755 xui/imp/scroll_bar_lower.png create mode 100755 xui/imp/scroll_bar_middle.png create mode 100644 xui/imp/scroll_bar_slider.png create mode 100755 xui/imp/scroll_bar_upper.png create mode 100644 xui/imp/separator_center.png create mode 100755 xui/imp/separator_left.png create mode 100755 xui/imp/separator_middle.png create mode 100755 xui/imp/separator_right.png create mode 100755 xui/imp/status_left.png create mode 100755 xui/imp/status_lower.png create mode 100755 xui/imp/status_lower_left.png create mode 100755 xui/imp/status_lower_right.png create mode 100755 xui/imp/status_middle.png create mode 100755 xui/imp/status_right.png create mode 100755 xui/imp/status_upper.png create mode 100755 xui/imp/status_upper_left.png create mode 100755 xui/imp/status_upper_right.png create mode 100755 xui/imp/tiny_fill_bar_base.png create mode 100755 xui/imp/tiny_fill_bar_left.png create mode 100755 xui/imp/tiny_fill_bar_middle.png create mode 100755 xui/imp/tiny_fill_bar_right.png create mode 100755 xui/imp/title_bar_left.png create mode 100755 xui/imp/title_bar_middle.png create mode 100755 xui/imp/title_bar_right.png create mode 100755 xui/imp/ubericon_frame.png create mode 100755 xui/imp/window_left.png create mode 100755 xui/imp/window_lower.png create mode 100755 xui/imp/window_lower_left.png create mode 100755 xui/imp/window_lower_right.png create mode 100755 xui/imp/window_right.png create mode 100755 xui/imp/window_upper.png create mode 100755 xui/imp/window_upper_left.png create mode 100755 xui/imp/window_upper_right.png create mode 100755 xui/kobold/button_left.png create mode 100755 xui/kobold/button_lower.png create mode 100755 xui/kobold/button_lower_left.png create mode 100755 xui/kobold/button_lower_right.png create mode 100755 xui/kobold/button_middle.png create mode 100755 xui/kobold/button_right.png create mode 100755 xui/kobold/button_upper.png create mode 100755 xui/kobold/button_upper_left.png create mode 100755 xui/kobold/button_upper_right.png create mode 100755 xui/kobold/check_box_off.png create mode 100755 xui/kobold/check_box_on.png create mode 100755 xui/kobold/cursor.png create mode 100755 xui/kobold/end_turn_button.png create mode 100755 xui/kobold/fill_bar_base.png create mode 100755 xui/kobold/fill_bar_left.png create mode 100755 xui/kobold/fill_bar_middle.png create mode 100755 xui/kobold/fill_bar_right.png create mode 100755 xui/kobold/frame_left.png create mode 100755 xui/kobold/frame_lower.png create mode 100755 xui/kobold/frame_lower_left.png create mode 100755 xui/kobold/frame_lower_right.png create mode 100755 xui/kobold/frame_right.png create mode 100755 xui/kobold/frame_upper.png create mode 100755 xui/kobold/frame_upper_left.png create mode 100755 xui/kobold/frame_upper_right.png create mode 100755 xui/kobold/icon_frame.png create mode 100755 xui/kobold/menu_left.png create mode 100755 xui/kobold/menu_lower.png create mode 100755 xui/kobold/menu_lower_left.png create mode 100755 xui/kobold/menu_lower_right.png create mode 100755 xui/kobold/menu_middle.png create mode 100755 xui/kobold/menu_right.png create mode 100755 xui/kobold/menu_upper.png create mode 100755 xui/kobold/menu_upper_left.png create mode 100755 xui/kobold/menu_upper_right.png create mode 100755 xui/kobold/overicon_frame.png create mode 100755 xui/kobold/scroll_bar_lower.png create mode 100755 xui/kobold/scroll_bar_middle.png create mode 100755 xui/kobold/scroll_bar_slider.png create mode 100755 xui/kobold/scroll_bar_upper.png create mode 100755 xui/kobold/separator_center.png create mode 100755 xui/kobold/separator_left.png create mode 100755 xui/kobold/separator_middle.png create mode 100755 xui/kobold/separator_right.png create mode 100755 xui/kobold/status_left.png create mode 100755 xui/kobold/status_lower.png create mode 100755 xui/kobold/status_lower_left.png create mode 100755 xui/kobold/status_lower_right.png create mode 100755 xui/kobold/status_middle.png create mode 100755 xui/kobold/status_right.png create mode 100755 xui/kobold/status_upper.png create mode 100755 xui/kobold/status_upper_left.png create mode 100755 xui/kobold/status_upper_right.png create mode 100755 xui/kobold/tiny_fill_bar_base.png create mode 100755 xui/kobold/tiny_fill_bar_left.png create mode 100755 xui/kobold/tiny_fill_bar_middle.png create mode 100755 xui/kobold/tiny_fill_bar_right.png create mode 100755 xui/kobold/title_bar_left.png create mode 100755 xui/kobold/title_bar_middle.png create mode 100755 xui/kobold/title_bar_right.png create mode 100755 xui/kobold/ubericon_frame.png create mode 100755 xui/kobold/window_left.png create mode 100755 xui/kobold/window_lower.png create mode 100755 xui/kobold/window_lower_left.png create mode 100755 xui/kobold/window_lower_right.png create mode 100755 xui/kobold/window_right.png create mode 100755 xui/kobold/window_upper.png create mode 100755 xui/kobold/window_upper_left.png create mode 100755 xui/kobold/window_upper_right.png create mode 100755 xui/main/button_left.png create mode 100755 xui/main/button_lower.png create mode 100755 xui/main/button_lower_left.png create mode 100755 xui/main/button_lower_right.png create mode 100755 xui/main/button_middle.png create mode 100755 xui/main/button_right.png create mode 100755 xui/main/button_upper.png create mode 100755 xui/main/button_upper_left.png create mode 100755 xui/main/button_upper_right.png create mode 100755 xui/main/check_box_off.png create mode 100755 xui/main/check_box_on.png create mode 100755 xui/main/cursor.png create mode 100755 xui/main/end_turn_button.png create mode 100755 xui/main/fill_bar_base.png create mode 100755 xui/main/fill_bar_left.png create mode 100755 xui/main/fill_bar_middle.png create mode 100755 xui/main/fill_bar_right.png create mode 100755 xui/main/frame_left.png create mode 100755 xui/main/frame_lower.png create mode 100755 xui/main/frame_lower_left.png create mode 100755 xui/main/frame_lower_right.png create mode 100755 xui/main/frame_right.png create mode 100755 xui/main/frame_upper.png create mode 100755 xui/main/frame_upper_left.png create mode 100755 xui/main/frame_upper_right.png create mode 100755 xui/main/icon_frame.png create mode 100755 xui/main/menu_left.png create mode 100755 xui/main/menu_lower.png create mode 100755 xui/main/menu_lower_left.png create mode 100755 xui/main/menu_lower_right.png create mode 100755 xui/main/menu_middle.png create mode 100755 xui/main/menu_right.png create mode 100755 xui/main/menu_upper.png create mode 100755 xui/main/menu_upper_left.png create mode 100755 xui/main/menu_upper_right.png create mode 100755 xui/main/overicon_frame.png create mode 100755 xui/main/scroll_bar_lower.png create mode 100755 xui/main/scroll_bar_middle.png create mode 100755 xui/main/scroll_bar_slider.png create mode 100755 xui/main/scroll_bar_upper.png create mode 100755 xui/main/separator_center.png create mode 100755 xui/main/separator_left.png create mode 100755 xui/main/separator_middle.png create mode 100755 xui/main/separator_right.png create mode 100755 xui/main/status_left.png create mode 100755 xui/main/status_lower.png create mode 100755 xui/main/status_lower_left.png create mode 100755 xui/main/status_lower_right.png create mode 100755 xui/main/status_middle.png create mode 100755 xui/main/status_right.png create mode 100755 xui/main/status_upper.png create mode 100755 xui/main/status_upper_left.png create mode 100755 xui/main/status_upper_right.png create mode 100755 xui/main/tiny_fill_bar_base.png create mode 100755 xui/main/tiny_fill_bar_left.png create mode 100755 xui/main/tiny_fill_bar_middle.png create mode 100755 xui/main/tiny_fill_bar_right.png create mode 100755 xui/main/title_bar_left.png create mode 100755 xui/main/title_bar_middle.png create mode 100755 xui/main/title_bar_right.png create mode 100755 xui/main/ubericon_frame.png create mode 100755 xui/main/window_left.png create mode 100755 xui/main/window_lower.png create mode 100755 xui/main/window_lower_left.png create mode 100755 xui/main/window_lower_right.png create mode 100755 xui/main/window_right.png create mode 100755 xui/main/window_upper.png create mode 100755 xui/main/window_upper_left.png create mode 100755 xui/main/window_upper_right.png create mode 100755 xui/map_preview_panel_off.png create mode 100755 xui/map_preview_panel_on.png create mode 100755 xui/monospace.png create mode 100755 xui/palette.png create mode 100755 xui/regular.png create mode 100755 xui/status_preview_panel_off.png create mode 100755 xui/status_preview_panel_on.png create mode 100755 xui/text_box_panel_off.png create mode 100755 xui/text_box_panel_on.png create mode 100755 xulkan.h create mode 100755 xungeon.h create mode 100755 xuxuxu.c create mode 100755 xyntax.h diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..906d731 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +xop +xscii +xtatus +xighlight +xhallenge +xuxuxu +xarbon +xource diff --git a/LICENSE b/LICENSE new file mode 100755 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. + +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. + + + +Copyright (C) + +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 . + +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: + + Copyright (C) + +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 . + +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 . diff --git a/README.md b/README.md new file mode 100755 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 index 0000000..c2e2135 --- /dev/null +++ b/compile.sh @@ -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 index 0000000..5ec3b17 --- /dev/null +++ b/install.sh @@ -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 index 0000000000000000000000000000000000000000..7eae4d25f40f38ba58419fd518048020c3af974e GIT binary patch literal 63264 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 z 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 literal 0 HcmV?d00001 diff --git a/test.c b/test.c new file mode 100644 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 + +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 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 index 0000000..3efd312 --- /dev/null +++ b/xanguage.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 index 0000000..0e453b1 --- /dev/null +++ b/xanguage/ada.h @@ -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 index 0000000..351c2f3 --- /dev/null +++ b/xanguage/bash.h @@ -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 index 0000000..131176d --- /dev/null +++ b/xanguage/c++.h @@ -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 index 0000000..8005724 --- /dev/null +++ b/xanguage/c.h @@ -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 index 0000000..652b10b --- /dev/null +++ b/xanguage/common.h @@ -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 index 0000000..d5a043a --- /dev/null +++ b/xanguage/d.h @@ -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 index 0000000..ca99f20 --- /dev/null +++ b/xanguage/eaxhla.h @@ -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 index 0000000..eabf301 --- /dev/null +++ b/xanguage/flat.h @@ -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 index 0000000..e24923a --- /dev/null +++ b/xanguage/fortran.h @@ -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 index 0000000..38919e8 --- /dev/null +++ b/xanguage/go.h @@ -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 index 0000000..5766d29 --- /dev/null +++ b/xanguage/haskell.h @@ -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 index 0000000..1509e86 --- /dev/null +++ b/xanguage/lua.h @@ -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 index 0000000..21bac25 --- /dev/null +++ b/xanguage/pascal.h @@ -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 index 0000000..ccd8dcd --- /dev/null +++ b/xanguage/python.h @@ -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 index 0000000..411f580 --- /dev/null +++ b/xanguage/valgrind.h @@ -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 index 0000000..c70de61 --- /dev/null +++ b/xanual/adc.md @@ -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 index 0000000..5460984 --- /dev/null +++ b/xanual/add.md @@ -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 index 0000000..ce79ef2 --- /dev/null +++ b/xanual/and.md @@ -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 index 0000000..da34cdd --- /dev/null +++ b/xanual/call.md @@ -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 index 0000000..8530e76 --- /dev/null +++ b/xanual/cmovcc.md @@ -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 index 0000000..88eb3ff --- /dev/null +++ b/xanual/cmp.md @@ -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 index 0000000..faa890b --- /dev/null +++ b/xanual/dec.md @@ -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 index 0000000..3407c95 --- /dev/null +++ b/xanual/div.md @@ -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 index 0000000..6b7fd8b --- /dev/null +++ b/xanual/enter.md @@ -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 index 0000000..75ff099 --- /dev/null +++ b/xanual/idiv.md @@ -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 index 0000000..1bb5c76 --- /dev/null +++ b/xanual/imul.md @@ -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 index 0000000..9207cd5 --- /dev/null +++ b/xanual/inc.md @@ -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 index 0000000..afc0e47 --- /dev/null +++ b/xanual/jcc.md @@ -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 index 0000000..65c5967 --- /dev/null +++ b/xanual/jmp.md @@ -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 index 0000000..9414082 --- /dev/null +++ b/xanual/leave.md @@ -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 index 0000000..2e91c6c --- /dev/null +++ b/xanual/mov.md @@ -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 index 0000000..10ae89e --- /dev/null +++ b/xanual/mul.md @@ -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 index 0000000..e919a4e --- /dev/null +++ b/xanual/neg.md @@ -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 index 0000000..aab6665 --- /dev/null +++ b/xanual/nop.md @@ -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 index 0000000..545dccc --- /dev/null +++ b/xanual/not.md @@ -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 index 0000000..cad76ef --- /dev/null +++ b/xanual/or.md @@ -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 index 0000000..bdc0664 --- /dev/null +++ b/xanual/pop.md @@ -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 index 0000000..60ad851 --- /dev/null +++ b/xanual/push.md @@ -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 index 0000000..65aa948 --- /dev/null +++ b/xanual/ret.md @@ -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 index 0000000..9ad236a --- /dev/null +++ b/xanual/rot.md @@ -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 index 0000000..537839d --- /dev/null +++ b/xanual/sbb.md @@ -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 index 0000000..79c815e --- /dev/null +++ b/xanual/setcc.md @@ -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 index 0000000..a053948 --- /dev/null +++ b/xanual/sft.md @@ -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 index 0000000..179b2ec --- /dev/null +++ b/xanual/sub.md @@ -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 index 0000000..c3020e9 --- /dev/null +++ b/xanual/syscall.md @@ -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 index 0000000..82d8347 --- /dev/null +++ b/xanual/sysenter.md @@ -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 index 0000000..1261727 --- /dev/null +++ b/xanual/sysexit.md @@ -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 index 0000000..251d7d7 --- /dev/null +++ b/xanual/sysret.md @@ -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 index 0000000..9b7abf8 --- /dev/null +++ b/xanual/template.md @@ -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 index 0000000..81b28b9 --- /dev/null +++ b/xanual/xor.md @@ -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 index 0000000000000000000000000000000000000000..68c322ecc7e50f603d77ca1f7d17bc13baf43320 GIT binary patch literal 81672 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 NkdyCh{71;?{4Zddg?<14 literal 0 HcmV?d00001 diff --git a/xaptor.c b/xaptor.c new file mode 100644 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 +#include +#include +#include + +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 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 +#include + +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 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 +#include +#include +#include + +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 index 0000000..6c0f7bd --- /dev/null +++ b/xarticle.h @@ -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 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 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 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 index 0000000..2e97aa4 --- /dev/null +++ b/xhallenge.c @@ -0,0 +1,531 @@ +#define use_fatal_failure + +#include +#include +#include + +#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 index 0000000..2ce3364 --- /dev/null +++ b/xhallenge_list.cfg @@ -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 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 index 0000000..aa792c6 --- /dev/null +++ b/xighlight.c @@ -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 +#include +#include + +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 index 0000000000000000000000000000000000000000..e19639b206e71a3fe8bf8561c2d7cda0a5925427 GIT binary patch literal 35224 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 Hr15_MSnAun literal 0 HcmV?d00001 diff --git a/xogueout.c b/xogueout.c new file mode 100644 index 0000000..7011063 --- /dev/null +++ b/xogueout.c @@ -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 +#include +#include + +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 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 +#include +#include +//~#include + +#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 index 0000000..dc6aeeb --- /dev/null +++ b/xop.c @@ -0,0 +1,43 @@ +#include + +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 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 +#endif + +#ifdef use_jxl_library +#include +#endif + +#ifdef use_jpg_library +#include +#endif + +#ifdef use_tga_library +#include +#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 index 0000000..91754ad --- /dev/null +++ b/xormat/jxl.h @@ -0,0 +1,68 @@ +#include + +#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 index 0000000..e7b5bdb --- /dev/null +++ b/xormat/png.h @@ -0,0 +1,106 @@ +#include +#include + +#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 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 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 + +#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 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 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 index 0000000..6b606b1 --- /dev/null +++ b/xrocessor.h @@ -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 +//~#include + +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 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 index 0000000..ad22a13 --- /dev/null +++ b/xscii.c @@ -0,0 +1,99 @@ +#include + +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 index 0000000..b0be1ab --- /dev/null +++ b/xtandard.h @@ -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 +#include +#include +#include +#include +#include +#include + +#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 + +#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 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 index 0000000000000000000000000000000000000000..eb8c8135979a1ac1d81392d3b07457e592831cde GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6zukN zaSVw#{5H&z?|=di^OWtMH0)mM$!dM|%2*-T70xDo+;E8q$ApRU=RUAspUZG1D)we{ z_Vk)oTc$v*_s3>Wel%g~7ghH!f;yTE#uf~#8fI3iPRS@-5)J5h4RjWR Mr>mdKI;Vst0N@x-2LJ#7 literal 0 HcmV?d00001 diff --git a/xui/common/fullscreen_on.png b/xui/common/fullscreen_on.png new file mode 100755 index 0000000000000000000000000000000000000000..5d1c0b303c45fa79e56ae7fe137cf97bc34b3830 GIT binary patch literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6zuhM zaSVw#{5I?)?*RoK<|&*v>fOQ$>}x|_O}!AHEK*;2!=g`dsY650pMo~~9q(8cY<+er zE_?42?KgrQL6zqB=7_YfS)y;bs6WAzamGQ$0M<7r*-e>mDMgoaZ($8%o0Ptc`PH*2 zjM{0da$oMb`*P>D8}AI8YIq{`cOGTbnAE4pw5Q(fvZ&zSU@49Z8yR2f%PwN>6x|DS O7=x#)pUXO@geCw+3Qw;9 literal 0 HcmV?d00001 diff --git a/xui/common/map_preview_panel_off.png b/xui/common/map_preview_panel_off.png new file mode 100755 index 0000000000000000000000000000000000000000..d0fb58af34677080f0a3df345b85eab4a16fe1dd GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6s+=e zaSVw#{5H&y?|=eF@T2HTk@-hY@7dYe;^}j1^%1d5ouv#8Mz4;~ocEwgc)=N&Q+i6l zcBkYVi%T{hIrn<2@1v|W;j0C>jMnU)w&&T#jtxCJcUuG)7=g%}@qGQeo4h7g++X^m tf~ETW+)l~%C!arheTG4;CTl}U$@|0d$sNr9ynwD?@O1TaS?83{1OU$MNMry2 literal 0 HcmV?d00001 diff --git a/xui/common/map_preview_panel_on.png b/xui/common/map_preview_panel_on.png new file mode 100755 index 0000000000000000000000000000000000000000..08dd569284cc2dfd49a289bbec82547e6cea65bc GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6s+-d zaSVw#{5H&y?|=eF@FVUY|D}I2#XURgtKyS%DNc2pN3td>!=ym_b6;4l&t?#v7*Lir z?^ED6j#-PlRmmP>l4#{*Ot_jmuf8x91RQ{5nL7jiqGdQxEQ&h w{>rRN1tms7?P%X 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 AiU0rr literal 0 HcmV?d00001 diff --git a/xui/common/palette.png b/xui/common/palette.png new file mode 100755 index 0000000000000000000000000000000000000000..8a8ab27c131fc01974627ef1a5083f39346ff98b GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQfx`y?k+$Y2!1;6t_M<_1s;*b z3=De8Ak0{?)V>TTSmf#A7@~3h?D>tp%mF+M7uk~-*BAUg|0VnbM}SJahl%E;gve{5 z>i60A?KO-SeQxn^37@*U)#){|*ES?i%e=YqaJuT9U==U7!$(>tO8G9EC;vzALhn%oc$@@B=5UY_ePsB7czopr0P9vr Ab^rhX literal 0 HcmV?d00001 diff --git a/xui/common/regular.png b/xui/common/regular.png new file mode 100755 index 0000000000000000000000000000000000000000..0e5bfe7e285393030848adc8626d3743c903644f GIT binary patch literal 9327 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 literal 0 HcmV?d00001 diff --git a/xui/common/status_preview_panel_off.png b/xui/common/status_preview_panel_off.png new file mode 100755 index 0000000000000000000000000000000000000000..fdb51734ab908b60be599ec008c9b7786c1d3fe6 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6m0f% zaSVw#{C1il-vI*-=7o>e+H{?tv{HI$prV1u`l(s3-*_wIgTe~DWM4f DA6Q5d literal 0 HcmV?d00001 diff --git a/xui/common/status_preview_panel_on.png b/xui/common/status_preview_panel_on.png new file mode 100755 index 0000000000000000000000000000000000000000..530fc12f183e0aea5107202f0ff7730c19c3bc3c GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6m0c$ zaSVw#{C3(w-U9|4%nOs4zRjN~dSbP`*J7s!fq&M9M5ntmC75K1S>4}q=(T1;m&Yn= zpw z)*d)CXCwD2iCY2^Op=Tue4S<&d=ZNOvS)e3hN{G0d!f>gTe~DWM4fMkhfy literal 0 HcmV?d00001 diff --git a/xui/common/text_box_panel_on.png b/xui/common/text_box_panel_on.png new file mode 100755 index 0000000000000000000000000000000000000000..0576c966d6e20681f00494fbbbf687b6b320bf1b GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6ioAU zaSVw#{C27%-vI>8a@w?8 zk)isp-M6xSD*3eA#p~3wbuK@)F)g3|W6^WlqfJ-2FPAg0#_=tyXn5oBD^_6Ye^v$t a1BM?{M3ZEG6r2Xy$l&Sf=d#Wzp$Pzfyg@1e literal 0 HcmV?d00001 diff --git a/xui/dwarf/button_left.png b/xui/dwarf/button_left.png new file mode 100755 index 0000000000000000000000000000000000000000..0631351954c8bf08e570d7433c2078b12b7fc47b GIT binary patch literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&h| z;us=vIXNUK=-2usOO7xc-kf$eDIh2)sew_AjVYl*gMs0|1D4y{cQUU8DrfL?^>bP0 Hl+XkKZEGF( literal 0 HcmV?d00001 diff --git a/xui/dwarf/button_lower.png b/xui/dwarf/button_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..01ce8422b0eb75a38c511cffcf3224b65cd237bd GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&D; z;us=vIk}{;@aOpkb^}8J1{To`cXpTa?{C_&#e~auK?Ea%gc)!Bi#YjHK=llsu6{1- HoD!M{` literal 0 HcmV?d00001 diff --git a/xui/dwarf/button_lower_left.png b/xui/dwarf/button_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..f75c4de8cc07b7d2e452a632cdce30a56f67cab9 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCq3z z;us=vxwY>g?*Ri2=DAvv?-cMHEr?UC3=GW@@q5Ia-p#1vU^-LN;ppPFuo=sjzTKP< oEm)ZUV_7`o57{opHMb{A&#V@5Pjk;@0UF2P>FVdQ&MBb@03H)6+5i9m literal 0 HcmV?d00001 diff --git a/xui/dwarf/button_lower_right.png b/xui/dwarf/button_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..27ae52384a70ea6aaffa1d80e6181537dc1d667e GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`v9 z;us=vIk}{;@aK63*6;7`CIZ5MknJN<{UX)*E6^MUPgg&ebxsLQ03Ze@^Z)<= literal 0 HcmV?d00001 diff --git a/xui/dwarf/button_middle.png b/xui/dwarf/button_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..f44ef7684384e89fb7186d9d58907323914e55a3 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@ALX t;us=vIk}{;@aOpkb^}8JhQrQ`40oj&Z>z8|)&Ny7c)I$ztaD0e0syo@7AgP$ literal 0 HcmV?d00001 diff --git a/xui/dwarf/button_right.png b/xui/dwarf/button_right.png new file mode 100755 index 0000000000000000000000000000000000000000..6ccd9af362eb1f8288237388972eff5f8ef331c0 GIT binary patch literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&h| z;us=vIk}{;@aK63*6;7`CII7H Mr>mdKI;Vst0885;#Q*>R literal 0 HcmV?d00001 diff --git a/xui/dwarf/button_upper_left.png b/xui/dwarf/button_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..e6bde500e9d49a1a139c45b3380094143380d67d GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`#B z;us=vx%JFJP6h>@qZig&c&5F)F?Z?e7oGtJ&7QkU8B8@%IeCWVkE6?z_RZq)3=?)g fZ|5zKbybaUT*~!SD9-UB&=dwwS3j3^P6z5)tq2?rslloHR-32ulg80p||U8$J$U mN1DzYTsEV#kwIYv0|U!k;rf|&ks3g=7(8A5T-G@yGywo$5i8{Y literal 0 HcmV?d00001 diff --git a/xui/dwarf/check_box_off.png b/xui/dwarf/check_box_off.png new file mode 100755 index 0000000000000000000000000000000000000000..5a0b5d1c1c541fcd9037809dfe9aa0ca8551fe2b GIT binary patch literal 383 zcmV-_0f7FAP)j^pBAO)92wX(M2v{WY$nz)y)rbg6 zDMw2pS>VhJhzLPR_*9`+B3s~A4tS(2)!N@%B@!YYJv$;&|42mKuz270Sa~*y>XVtL z&(Gvgo{8TKXj}818cPIPZ)TISo()l;C*gTDN?^@4__1wQZZj(stKQ#BfnEj8`zzh^ zUJBGo(Bkan$A2i`HK{8q+(UudguEKRqQX)$T5U?9&8V8ELQC=^%}Be1W(JbsUa&e9 ztte(y5Ho{_q?e&oBN4TjXy9*qfkq<2EO2u%X-PzlJOD1?GB7=kbqLNFLYF_=Oqh(aJ_ zKUVj=O!CK0U2fB#-Zj3wk6z1>?4S~ecz{7Lv(uirnm7?z=tGQAg>ag<_a3YQ5mg9R z6K7^K01aZQWo`wKgNPu;c$5%M6Hh4tB7#v7zFasvF=^sj4YZ&%*UJA(CniKZ@=G%v z5s5EiW|-HtzTcnOiO>?n)LTUPH-%7L>%A8RwU~PLugrRBd>i(L8^ZvI2wMoSJRYz$ zvVTE7*Y*@~_ZDP`xslbpuCU+l-6!Y<7sqYnYqo^|JCT}Q&i*X`mpgEFLCSuP@x1_- zJCKij_#Y0`s=Viv{9OkSvFnWg#D$?|)M~{5084I4M7GVSY`3*YDRmDoL(M3= zu{YYWADks!9?8x#TWu=pft8#&kA2MSz6_-jgw@4F690BDkRU8V6IU-LC4|*jE{Tgp s_*`&Ue{dvm^%Ph`F!R{u^f#~PACiFrTzM!Tc>n+a07*qoM6N<$f=|l4$N&HU literal 0 HcmV?d00001 diff --git a/xui/dwarf/cursor.png b/xui/dwarf/cursor.png new file mode 100755 index 0000000000000000000000000000000000000000..918d594848347bb3fc7a3bbe97db6b34be6fb5c0 GIT binary patch literal 378 zcmV-=0fqjFP)C;`O- z=VqvM-fP20uK;OWcp*gD!DnA>y#^GY{d6_nMp*~|oUZjw6-NhMgwW_T ztYJ%52RL2VjrJifT@-s*4r2FqZm^fd5SuFO2k;#y$Mg^F3;2J)dWuF740K|Gkqn)f zc8FjUR)?PLb`Bt0EEY(b)$szvNR~YN-+)wwiGQtelp$yo+l23ShWXK}T{8}MUpp@KmMh8 Y01fqxuz9)X#Q*>R07*qoM6N<$g1^0+IsgCw literal 0 HcmV?d00001 diff --git a/xui/dwarf/end_turn_button.png b/xui/dwarf/end_turn_button.png new file mode 100755 index 0000000000000000000000000000000000000000..b89b15c26f67c6b2bf4ec6e08da615a862e01670 GIT binary patch literal 1351 zcmV-N1-SZ&P)Nl<{{KNlpF{*91c(Ud^Vxz2?g#dp3qB+;0I-O_`BPdp zq>Nj{tt^^6q{544g;aO>%>`ddLN55#Ef5-5YhASRwJPj_FCpMg^F-QC3^l?@DKUxh z=C@Hy!9CaFOfBGZ-SXJtxZ5s^fLLd1TrL2F1NNYBG75zL1hmE^DezGOQsD0$0R}D; za8T7YBc*B0ae$~i1+v;f&EOvlqB$Q>x&?|>zS1~#NOBZ`@2UY(@O-?PFCmmUK_`S2 z4YO(>LJ+pSMudRw`+zO_1j$$Y=9K8}G=5(qW z>+tc>-9QexhNEY8sKy|+%wOyW^Z+0G#xMg)6&ta`$465AwbnNGSK`;K8bLRn)`o5- zSz-hC?`fLu&VC}o<^A1)C?!FRqXjRBU`{8P1b8clSRZ?zRGs4pI*#4c{__5Aji6zM zQEGKNguo*ce2)B40$4~JjC>afYv4oUFW__K-#^N} zSiHto@VWBu*9IY@tMc-tB*dI1F-`SzWXQi?^8_CO{#g-V7fH|XleTi$~lMqbYcqB9@MJ*8^phJB?kG$a1 za)K!zy0ktZc)nL$nYVc3#W}&4_f%6K5KM}`P8hI$0m^9Y*irTfklUwJUP1>m8{cwFOPr_wonI>n)wjc`eN$2& z&~m3|y}1WgnGB`i7f`wN0WF1&u1ov$Qy@k{X?;M`t*%2tHqgTPiX5RDFn%y%tG7d5 zrZewSL&$PU()2H^LN*M_PN}#=M)!&E>8Rk@Yt&nzij?a zVEXEpLr`=a?>lV>{<9!v-t8QVn?*uuHCk4^WR>kZ29q~V47}BV6bV~sG4OW;gh<#z zTMVKPK4=859X9c3+7HS?PiKb+W1Ax3n#s<8Jne3WjSvvU`3HOpA`Z-B)B&XxOI(8G4K7-Bxamr4O}N6u#y0Ky_jkQwGZrUI ZU}g|fVv`ir-3PLU!PC{xWt~$(695H_C#L`a literal 0 HcmV?d00001 diff --git a/xui/dwarf/fill_bar_left.png b/xui/dwarf/fill_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..87232883816139279d35965c7b13c1cb4e7ade93 GIT binary patch literal 825 zcmV-91IGM`P)q$gGRA}DSSl!X1FbrH68gL70AuYItTnVn>D}fqZ!hJ2cg|wg+ zC?WR{1jaGJ#sqVo;f3L6S6Z!QHK@3V=vn%WrY3k}444^2l>NT7768!J0a=@>xwg!0T z+#%qfI={z|Ek3oyl|IIQcCXKG{ZGCt|CFAn@wJ;nLb^g}iRIZC0cM69 zXqV5+HwBx2kC~fR*h_QegJ1hW*wXsCKicOdAc9Hc%FN9qAwSwF?QKavkDGZ}<-p0{ z7s2qrFKWP#`lkYnwY14A!{=jC48gzc1Gz`L?8qnj{2F)ygA|^p9%yoXehs`wg?9G`)`?`(m0JUfr$ z8GJE;SXY|+zF(}+JqUoaKNDbydJKG#jUEAB-Y4~Lm3|i1!0*n$k>FS5wGsJZ3FVH( zx6TtZI53ZUf}5@K6Zl;ON{6zsO>T0U!7Xfb3;b!_=w?vHX#3!Ot2})+nr){;#6It7 zHFg;S0zO4H)d{@KgfcXL2?DW^O^$3XkpZ8?p2&Z6p`y`AMh2z^P|@yxc1O0vsla6? zmJF2a>fKr3V-r9DUNVnrWW4@u@UcvUv;HCi|Lgh($8J}?nOtMi00000NkvXXu0mjf DdSHSS literal 0 HcmV?d00001 diff --git a/xui/dwarf/fill_bar_middle.png b/xui/dwarf/fill_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..76ef017e8fd7f76438e3349af3394fd7fffb7d3e GIT binary patch literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9EHPk}Jw literal 0 HcmV?d00001 diff --git a/xui/dwarf/fill_bar_right.png b/xui/dwarf/fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..8aba62c420693042eec4186d36228d6e706a64da GIT binary patch literal 328 zcmV-O0k{5%P)-sIu^DC-;2cpzc8fXZw-*vbWOo80LeANBlEBPGfEN-< z9!vlaBmw|4uNGBxo{LD+lS65dnPFygi3mz3tpfgm#LfHfAie9vrC5ji8t}MuA&1Fz z9SL~kUjfkJ4l`?Br|iLKGobP0l+XkK D$UGWU literal 0 HcmV?d00001 diff --git a/xui/dwarf/frame_lower_left.png b/xui/dwarf/frame_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..f8ad153b4a59a978013430cc9215ad22ec70cfe9 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCq3z z;us=vxwZEo=K%vA=BJlD^DOwEKHTE<$#a3gWtkVrvPBHc7yLp`mSuc=aVWH6x3WRh p!EHvL>kod@WN_cu`F?*NC!>V0`<)AIyMe|rc)I$ztaD0e0s!o%FLD3? literal 0 HcmV?d00001 diff --git a/xui/dwarf/frame_lower_right.png b/xui/dwarf/frame_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..7dabfc1613ab2ac875743b0532a3e22ae94506ec GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}{2J z;us=vIXT6F$;->@|I{f{BoZpFt%>CE;bCELWYqx)e$?{t_I4KBQT|?T6;lZ#k1&U3 dg31#%h6U#Z-28vf+y^v@|I{f{BoZpFt%>CE;bA%OA%KBFdk0G?Z?9h(P%VR}tDnm{r-UW| D&UPBP literal 0 HcmV?d00001 diff --git a/xui/dwarf/frame_upper.png b/xui/dwarf/frame_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..e159058fb768b1a020eee89e19dd3d41ec054baf GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@Amg z;us=vIXNUK=-2rM_6GoXD)5D_71<;-^6uo&nFH|hj6FKD#pSe_>`3F-`x2q$WZkC ikAZ$_<<<6l1BTaAc%@j^bp!$pV(@hJb6Mw<&;$TZFDWko literal 0 HcmV?d00001 diff --git a/xui/dwarf/frame_upper_right.png b/xui/dwarf/frame_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..fa0d670b3ab13ad235e7d9b0bbb84a701a988e26 GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCpwp z;us=vxwY>g?*RoKX692Wa(cmO)1q7LR)ujWefaLTZT6DH_6nCN3>(gvuzNXPy1ju* p{)hUiw#cFdz6sWM-cDNmfuTrJr2gm@$ts|E44$rjF6*2UngD9CEbRaQ literal 0 HcmV?d00001 diff --git a/xui/dwarf/icon_frame.png b/xui/dwarf/icon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..c61f9e3c56ba11b0d56addafbf65d1b92f235e25 GIT binary patch literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6nyCE z;usQf`0ezAye$SiEavRIOIWWziV9-iGEpp}G3ri}_X9g|O?HWwDu-+L?APd@=~4Mc zEvBWz%)-TGQt9+{50;AX+hwg?=CbL*8J_h56E!EUd!Y14Ey1%VT>raJhUU@**LHms zTFe@M{c7w3pQH+=b*tjj)7mG@aq{ zx|K3gJ?_S7X;0=bE-+nhQuFH4S|Q$jujjnnz#V1(rh1RN&JIhTD$eD(6RtX-qP{M%y0gj=lTDq&o$a;>}Cq|EQ6=3pUXO@geCxK7IMu1 literal 0 HcmV?d00001 diff --git a/xui/dwarf/menu_left.png b/xui/dwarf/menu_left.png new file mode 100755 index 0000000000000000000000000000000000000000..0631351954c8bf08e570d7433c2078b12b7fc47b GIT binary patch literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&h| z;us=vIXNUK=-2usOO7xc-kf$eDIh2)sew_AjVYl*gMs0|1D4y{cQUU8DrfL?^>bP0 Hl+XkKZEGF( literal 0 HcmV?d00001 diff --git a/xui/dwarf/menu_lower.png b/xui/dwarf/menu_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..01ce8422b0eb75a38c511cffcf3224b65cd237bd GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&D; z;us=vIk}{;@aOpkb^}8J1{To`cXpTa?{C_&#e~auK?Ea%gc)!Bi#YjHK=llsu6{1- HoD!M{` literal 0 HcmV?d00001 diff --git a/xui/dwarf/menu_lower_left.png b/xui/dwarf/menu_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..f75c4de8cc07b7d2e452a632cdce30a56f67cab9 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCq3z z;us=vxwY>g?*Ri2=DAvv?-cMHEr?UC3=GW@@q5Ia-p#1vU^-LN;ppPFuo=sjzTKP< oEm)ZUV_7`o57{opHMb{A&#V@5Pjk;@0UF2P>FVdQ&MBb@03H)6+5i9m literal 0 HcmV?d00001 diff --git a/xui/dwarf/menu_lower_right.png b/xui/dwarf/menu_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..27ae52384a70ea6aaffa1d80e6181537dc1d667e GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`v9 z;us=vIk}{;@aK63*6;7`CIZ5MknJN<{UX)*E6^MUPgg&ebxsLQ03Ze@^Z)<= literal 0 HcmV?d00001 diff --git a/xui/dwarf/menu_middle.png b/xui/dwarf/menu_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..f44ef7684384e89fb7186d9d58907323914e55a3 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@ALX t;us=vIk}{;@aOpkb^}8JhQrQ`40oj&Z>z8|)&Ny7c)I$ztaD0e0syo@7AgP$ literal 0 HcmV?d00001 diff --git a/xui/dwarf/menu_right.png b/xui/dwarf/menu_right.png new file mode 100755 index 0000000000000000000000000000000000000000..6ccd9af362eb1f8288237388972eff5f8ef331c0 GIT binary patch literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&h| z;us=vIk}{;@aK63*6;7`CII7H Mr>mdKI;Vst0885;#Q*>R literal 0 HcmV?d00001 diff --git a/xui/dwarf/menu_upper_left.png b/xui/dwarf/menu_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..e6bde500e9d49a1a139c45b3380094143380d67d GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`#B z;us=vx%JFJP6h>@qZig&c&5F)F?Z?e7oGtJ&7QkU8B8@%IeCWVkE6?z_RZq)3=?)g fZ|5zKbybaUT*~!SD9-UB&=dwwS3j3^P6z5)tq2?rslloHR-32ulg80p||U8$J$U mN1DzYTsEV#kwIYv0|U!k;rf|&ks3g=7(8A5T-G@yGywo$5i8{Y literal 0 HcmV?d00001 diff --git a/xui/dwarf/overicon_frame.png b/xui/dwarf/overicon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..c54c9be29b8d7607c705a4c6ca1d2f442d55e591 GIT binary patch literal 273 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6g=$d z;usQf`0ezAyoU`qTopg5oOu)}(G_XKz50UpN+s0^VM;Gs^`AaDTrbx5#lgeLg^e{Z zwC9|GcKWlfI)RA-Op8BRs)w|8IB}dg6}pv2p-JNA+0_g-XLyv7syhUyuHSm;_~&Gu zrUUG!?8UzXzB#_}XXE)-eMSF8Lq-22rzt4iesDgsfh_}u4){!8HT8|p?+>SLzSFUP z!f?;GZpUi)(B0MI)O Mp00i_>zopr0P&-3eEW6FbqT|s}cx>p->9O5-i1FET&KjrmzsYmu;2i zqixi~UTP_aM4qQf#t9@hlGvB3LPX&1$crS*3}x>NjVi^xGXQM>$xCNlz~f-d!E_bS zt0q81n$2c*?Fu9He?a&~wB`3Uv+5mMAIaTA$a1bA-C2EyG6=NP}N@qYz+y(5A bhP$dhk9lZ#!%xz-00000NkvXXu0mjfqc?8g literal 0 HcmV?d00001 diff --git a/xui/dwarf/scroll_bar_middle.png b/xui/dwarf/scroll_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..19063a79dae554fbee972d91a2990c55412d6cdd GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwC-9vDsGobG$1gTe~DWM4f@^dYA literal 0 HcmV?d00001 diff --git a/xui/dwarf/scroll_bar_slider.png b/xui/dwarf/scroll_bar_slider.png new file mode 100755 index 0000000000000000000000000000000000000000..c54c9be29b8d7607c705a4c6ca1d2f442d55e591 GIT binary patch literal 273 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6g=$d z;usQf`0ezAyoU`qTopg5oOu)}(G_XKz50UpN+s0^VM;Gs^`AaDTrbx5#lgeLg^e{Z zwC9|GcKWlfI)RA-Op8BRs)w|8IB}dg6}pv2p-JNA+0_g-XLyv7syhUyuHSm;_~&Gu zrUUG!?8UzXzB#_}XXE)-eMSF8Lq-22rzt4iesDgsfh_}u4){!8HT8|p?+>SLzSFUP z!f?;GZpUi)(B0MI)O Mp00i_>zopr0P&-3eE&EY^sF+8dZQSG37gpW%s91hTa&SlvAMbu|^$?6a1}{ZipG z`|)^Tdt;kGp zb@S(x6f99;m^l0PZwB{l_2~@k=I@zKh)%e^$Ye#sKG!$}cB9goNW~Vbd#O`BXIv|Y zd_IqD=hHW9w>ESb_+C!4uSLzSFUP z!f?;GZpUi)(B0MI)O Mp00i_>zopr0P&-3eEN}oqY9E41s>M$(eZcVCWYW3?-1%(YwVwL? z4FXQBm(J>VZu|97)^pUXO@geCxlsaehd literal 0 HcmV?d00001 diff --git a/xui/dwarf/separator_middle.png b/xui/dwarf/separator_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..3db79c49a5375391e1fea3591cd909d82d56e737 GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwAm4k zwjbR>6Lpk+zBM#T60C5BCZ-KL>reNs?PDtY3R tfb9kc_NqtdKYJU}C;#&G`ai#`7&m(ra4$aHQ3-T4gQu&X%Q~loCIH*RUI73A literal 0 HcmV?d00001 diff --git a/xui/dwarf/status_left.png b/xui/dwarf/status_left.png new file mode 100755 index 0000000000000000000000000000000000000000..99020edee27228d3c5831f74dc5288dceede900e GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`m6 z;uvCaIyodL=-2usOO7xc-kf$esi3eh@c`SmH#ZMAtee)^=wy&}UiZUFT%c)I$ztaD0e0s!D?CUO7( literal 0 HcmV?d00001 diff --git a/xui/dwarf/status_lower.png b/xui/dwarf/status_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..1c0a3e7b093bfaafcdbfaf25fb04ddead6594e86 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`;E z;uvCaIyodL=+}7%#sp7q@8kt18mhm)<1J;5iHXrLYUpfqGRR_JW`3LzwCoN8LrS6O Vaq)?l?*lb6c)I$ztaD0e0svmqBcK2P literal 0 HcmV?d00001 diff --git a/xui/dwarf/status_lower_left.png b/xui/dwarf/status_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..fc161ccb41ce1bd427cebedbb43f8a4927d793fd GIT binary patch literal 372 zcmV-)0gL{LP)* z3Cyri^q7#u(MDTc272bQyDaMF=F3AoH^oE0V0-OLRfGbUi zF+Pn+g5>X5M8;R&mwdw2Pm}Xq7T3~1WaS6s+DQC^9rmPkS*RpcG z_t5_K^zPOxRCWDbFekkO=qJH00oN2D&;xuR5xDDiKJZePPz+x33Ac6TA%qPUVNb*) z-w=;L>5AB}ZJPi{Lcq+j+kC@W1D8sg2VA`ZR$KnB!8HMhNYi<++BU4Q-_}aGr6pXd z_mt8nfRAawVHnJ(S~CCu90}3owwYhOb_JM&*u5$JX(Go%yW%||x+O>H8u|j`ErBs@ S_^Aj00000^@R9M69mR*sZ~*Wz#{bK`*VoR>{{UKMJWPbm@(b}% zoFA~G07yc>LB(2 literal 0 HcmV?d00001 diff --git a/xui/dwarf/status_right.png b/xui/dwarf/status_right.png new file mode 100755 index 0000000000000000000000000000000000000000..99020edee27228d3c5831f74dc5288dceede900e GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`m6 z;uvCaIyodL=-2usOO7xc-kf$esi3eh@c`SmH#ZMAtee)^=wy&}UiZUFT%c)I$ztaD0e0s!D?CUO7( literal 0 HcmV?d00001 diff --git a/xui/dwarf/status_upper.png b/xui/dwarf/status_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..1c0a3e7b093bfaafcdbfaf25fb04ddead6594e86 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`;E z;uvCaIyodL=+}7%#sp7q@8kt18mhm)<1J;5iHXrLYUpfqGRR_JW`3LzwCoN8LrS6O Vaq)?l?*lb6c)I$ztaD0e0svmqBcK2P literal 0 HcmV?d00001 diff --git a/xui/dwarf/status_upper_left.png b/xui/dwarf/status_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..3d8c27165eee288e2abd968796b08ed4f0d8c360 GIT binary patch literal 349 zcmV-j0iyniP)zP6NtP5F1VnO1Wtotj7l0Z> z=ura-P=bg=)Vv0!X`08({8bYd=nzB%DW&;gW>Dq30Q`c89{Khr{uR->2qJpT#{?g( zi{f3c3zaaAD-iWzuTgQMR z@caNPgpM^z>ih+u29bw1xf`GaaU{6{gpJ~B+AG{nh={A*>v4G1bOS7t4j>qj7VH6u-)7v@m#3sVt#tAA;^rFoYRSmjr_Ej{D!3hZggR+wm5XwxT_cRtTG juiK621ULasfLgo(p*Pf^LlTHq00000NkvXXu0mjfESsP- literal 0 HcmV?d00001 diff --git a/xui/dwarf/tiny_fill_bar_base.png b/xui/dwarf/tiny_fill_bar_base.png new file mode 100755 index 0000000000000000000000000000000000000000..91f835c2f94e3b8fb62762fe877a045b2f2f4d8b GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg`npr$CtT@x&!cKtXFy z7srr@!*4GK@-i53Fkj4@S)ZEW;G}CH`S-!RCU0gThMe+MS&JCAEoNN5duvtWY&$0= fjt9JtxfvMjWS@#H-*k@`WEq2}tDnm{r-UW|vSuku literal 0 HcmV?d00001 diff --git a/xui/dwarf/tiny_fill_bar_left.png b/xui/dwarf/tiny_fill_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..bf129c0a6f197164e55d19f4959548343d79fd84 GIT binary patch literal 429 zcmV;e0aE^nP)tapBhMFuwz8DLBV2-M%pub;?6k@eR%Ihh+Y!6)?!rxaDNb6 z38I(8hk3>_O)3Cm2qHu;iLbXCVvH&Pn5H*~B0w(A%&^v~=reN;fs|jSCZ2xNQB;61$eu-3v5(N@|>!FUXB0qru05H+wvSj!*X%)BDxO^+iMH0VXJcw@q92b(rA{xgbIKlUL8(r_jpT>APuMH?D6~; Xy<=J~5@iOi00000NkvXXu0mjfSUj%c literal 0 HcmV?d00001 diff --git a/xui/dwarf/tiny_fill_bar_middle.png b/xui/dwarf/tiny_fill_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..a8722210635db97f8ffafb63d1090c718b22df1e GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg`npr$CtT@x&!cK*0!4 z7srr@!*8$o@*W7_V1BSqUUh2#cZTEfDM_i5FCM<-y*}PUf#Kx+%^v&w4!q5K&GPOH zO9HEmXTJ(V!{YGJ$n6Qc-#aicvIsaZNHcgGx>|Yili*E8&rggotJLpip7xIg+QH!I L>gTe~DWM4fZihJp literal 0 HcmV?d00001 diff --git a/xui/dwarf/tiny_fill_bar_right.png b/xui/dwarf/tiny_fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..c35665a1cb6ea10ac862257107da94c203b944d2 GIT binary patch literal 354 zcmV-o0iFJdP)?Jt%Zft~n$Yds(Vc-CIz}E-h8}E)pMEBlBW|q8jvxs!>s+4l~LXwDdpMZ!^N^zYe zF>?sug@iPy01qU;TENUOGY}C}70kR^q^k2+M0Pb9HmYRR|BbqV+C&6fH!(!(+Y8B^ z_5Tmjx~|-lT*vDgF#R+kgSTq*M!-~_4SVFX!7uL?M)v3 zGOHG?(o-Z>5csvKLPd^Gs_{PV?FCSL;Qz-rUmH+?%07*qoM6N<$f<@(& ADgXcg literal 0 HcmV?d00001 diff --git a/xui/dwarf/title_bar_left.png b/xui/dwarf/title_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..96a3bbb906f348661ef059f70d85d2162ce5ab01 GIT binary patch literal 539 zcmV+$0_6RPP)6AfwM^&%ohMCNE9BILcFE2(e&xd&42%75%YYX~>U55)WDpSQGn;BE8cWapDe zW**-F-}uPMSYJD$=52qK_uVI9fc_6w8gF#Qy~te*%7;U=z-(NIZ>(xE&`AW zp(Q>GKno((+_K-uA|axEt4J`gvE*1a) literal 0 HcmV?d00001 diff --git a/xui/dwarf/title_bar_right.png b/xui/dwarf/title_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..d8dadd2222c9151d086dace677eb5c4a5774770b GIT binary patch literal 434 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 literal 0 HcmV?d00001 diff --git a/xui/dwarf/window_lower_right.png b/xui/dwarf/window_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..cff21bd8d96d5163dcf834f86f8c612af46b3ff2 GIT binary patch literal 1466 zcmV;r1x5OaP)h74In2~HZNXuOr)mMCm9#&fXx8daIJOpyfJ2c7l^m(07M+w@YKcl zyfJ3n8$wJ6aO$(xdRkz!4q!PdjZZ;9M9^Bl4Fcaw%=nxo(v-R#{|x~kqWdg&ZPoz5 z28YITy|6h3$YMnPXk>Or31M$9;26-&%Wlxxz3#4881|?IxPpoqHGej~bM{lUKuNav zm$g92Xe!*q7`mo(x0Gfm(GRhhQv#xz4p^HF83PJOG*(~>qiP9g0KnFL2Igi!oprVz zSc(C~Qdm#L#Tb6ZvsCJq{GITc*utm~JmYDY4ut^rW}aff{c?Fa*2Yhcd$Msd!q3@( zmER@^!h=ROUd}iT0C?^}=^ki!d>%sRu2)b>fy`RF=l~Wwv+8rMKc~K;Wgu^Kem!a= zZ?>sb?wU&XV9hUJ`+%U%+Jk@v_t0b-ehTw^%#Gbm3K6n4xKZh)S_05GH!=wT@F_O9 zrNPVLRR~SN?4JN&OwHn}uCJ6zLO`Ht{SOw1W~g`b1VML?z$hVrwcBGrBpy7)gis2< z0wF4`#nj_q0m!;w$Pm~|bQg~aRRKgmoO1KAgcbvpf?x-9Ml1A}fEN%cogEJE2@(<5 z?&=+-5ZFlR`uti#i9tBDCFW-FZXO4~W(e#R*iI=D&wUcYXLW@Kau7;m0z>d-eNK@? z1bFVfOu-O72SBF*THF*ELkJQ1{FEX;13<>imq2hbd9aV*di$NehY(eahX5cV=+F3o zFduzuvUEcVf}w{e;9w^ZgI_P?c*0xy0Um^m5_L%|NjYu_JYC?fJpgb^$enBBrFAs` z#u(WOdy>Oz2FGT3O)-YmXo(`_`>oQilPz=k1GzN;>jcl>`*T+}1R#wrfnbbr6ZKQc z#ZOFB&Wg>@;-xxasaGkDPkon-uf7Ck2%aaTmP1yy=yb8*3MV1e(Ag~rZidk5;#3(6 zm`kPiu4xck7!e3wS`IJhgc{?gs_}DyqS|~2TXn+WZE@Ma^a_;O6LOZrR-Ld3Ku+I& z6#$TDyzAr+We|=SO=_>dL;%SSE}nZp0I=qFmZSL)4gpYuyqoz}0YtjD9206l*wT92 z4S>SAd)uZ<)1{bDT36JBP|X7-2o?zZ?yZCoLI{DZ87#$4EeK7Gb!czK_2^)*el}?R z;22vDIW8Y=zEsx%YdKdwAQAq*I%`*U^53v2A#3y+5NbV*(y*JgeV^P-;q!F4cz@;p ztFxYVXfW8sB;OPGvzS7(0Xx8iJ!j-A41|Ah(YiI;oP*u+ppKec%_~X z>-twAcv5)n+1i-#MC5%(owe7$Pjzpdb|@%iQ`Ozt0~AHIz!HR|$Iq4^q&m0^pcaJ9 zOMn}YsU6nVm{srK@5tpaZD>4FB-w|0lrCR0y1%s;ay`2h2t;;@1uUE*f$ZJ#xNbin z@{B$&2N@9MM(5GRQ1yL*6ogO{EX9Sd_5ef#rBu=rB!rIx5O!?V-iKL09{g~^(sDRr zgiEcFZYzb&()*ap=g4TO7>@!FimfJ93#`4*Jr~UwGX!Xl@c^kanw-sxT}EP?eDC{t z@_?-^v90a2aAx*4oU2gh0Y~NEm|MQ>}03=No U`clvXK>z>%07*qoM6N<$g4)-fb^rhX literal 0 HcmV?d00001 diff --git a/xui/dwarf/window_right.png b/xui/dwarf/window_right.png new file mode 100755 index 0000000000000000000000000000000000000000..0c0c404dd9cc8f6744f9283cd5dbd7a0d2793921 GIT binary patch literal 492 zcmVur#Auv{z7H5a5b+ZcA)G`6>$*bAVXcL<)}!=-bB+b(oXb9YlwOj? zfM<*xiLxMB07Qi6wiOFYW8k@MfQaY6Ab{lVd!?$y0RWb>L^|idD+Pk6TD%D${5r1` z3!q6whzLOR0x1wYL`5}_E)~_p(5#{}$I>&xAu0;8OpE32p9V-}iHL^)1W}(%QxIv) zD7`P`8S5#kn!Ta&r8y)W{!}MY-r0mPN4-gx2G;$iG=dOdtH=EK2o1oCCk_udmwo3ppSHi2QIF z2eBWf4`!cyZJ*r40k?QF2SaAG5(m<@0p0ms2z9B^Y|X3@-|AKZ298AKNVXXkP0DIV5EC8;jG#icRrB= igJTc%yYv4wAAAA5AHdYr^A^4U0000^;SCauDHe9h|x3g$YFc^BIG~`hwIC96GrNom;U zQqm-0N_{(^Bb*Y5EygZLGM*p4#W)O3>BT#uU1v$(j|$QN`~}jI5;!6?fipWM(X#t; zJZq`xW}PK{^O2;McnAT!_sx)GydzSRazx;s&!#G9eL)=0dNhzV=<}Vn)Ys!t?NPsl z)A}1zyYH<4ak1hx+d^8Pg`@;(xDu>^5^^ojLR#1s zEFtd?U9uo3C~D>nGfXb=BiV=j#%mDq1z$Wa{D;;WhzJnTz3x4XG48uh1%QZPj5!nn zf1fc1i0FI(@<;6rfxm~x=>Vjltd@I@P~}etAR!PDD5ZA$LTl~x!=6Ch&hZ03pRf`N z0qoyY^AK@%hUd-=J|4baJ|!GsJ3wGfAR=hHZvL9lf%3VSaHxEo?sxAMjrj}!)DHk8 z1Vn`A{SMd11D^N$?Jb8+PUdml@~#pmOh(?!cN~&nHYE?2!kQ zWO8eA23~cpJ?0=vlZcr^Ep7Z+Ys0l5xG>mT7t`tQ*K>#|2sP@I%N85vYOYooRIQB) zPQ4F-%^~KWj83Y($;uXbn-Ycv57hm~!~GXZvncpK^h z4w2N?ae|v_0a;l|2qnVHm0<`7@VtcGE{5k!Ao*aZZpAdsUfK`Q0nt-iXZ~HA7y(s*WIRL{^qRH>Av=)~@y?SNIsHRS=*&eoIZ@>uPDjWz7$Yoh!Gx zjWLsScu}b39%-)imbN-h(6xDEP=2!PuL9r5qbM-Aq1}}(NEjh zYaqyZ)WaH!CJ=+bLNWviMYgm{A;?)!ZN7N!0wCOJRW}Xh30|Hca|5M2*TDrC>i8^IQ>!mONqxVF_)aKQI3=1?R$C8-Fkv+ z0i5};^KJlg9#wUq4t(Z672>3(?B)abK|`e!^jf>)dloIDps!e*55dSVm}@FoCO||{ z;g6`+Vy4CrV#i8%sj~pIUFQkk2K~Oh)t|LsX$P8*l{m_5A8>sfB-2FYr^B@69n4;;+U4$|2(o=VqXWK^dA-eI{@DTVbKYO-Jq|l1+F6I o_lf!)PyYYkT>yMy9b%707*qoM6N<$f|Q7fC;$Ke literal 0 HcmV?d00001 diff --git a/xui/dwarf/window_upper_right.png b/xui/dwarf/window_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..81a118d84c71cabbab47ee86975db6dc93f8317c GIT binary patch literal 1744 zcmV;>1~2)EP)ohLt=mbch*)6PjxGuj?N*xk-`)2@3Y>_}juqGbX z+K+Q*X@)~)>OQ*9$6Vj{)djx7PfLh#oQVi(t-T=d^X?=6e(d##2({L|UlLsVX8_BD zWGH`AYYk|OcPCtaf8l<+HIFV}vDe>kH}4w$UAgnAPJ@86ynw!)*mvRUDK*Lbd}O`u&YyBD2|mCMT9U?? zcVg8eHK_(5z?O?(D+oE3#%mW18Fnr1m9&(Q0H6K7F(xQ+TEkoHf&i& zoD`Z-yC8sfdZYJ6&~@Do@8ncEfdvtr1{BJ}*I7!&1-(>|EVy;~{66sA>)UE$4ranH zf*$fsre-yGQDE=3RdxsgpNPQR+vln)u5z7j-cgKP)FL58Ye3Y`M*9Tt?d2EXF4Ry> z@bgEjkl>EIoCBCU5fP*uGt^bj_xTsyOiQd1ufzmKa51jS9VHbDI)DxWzoxb&OneU^ z7EnxJFi8@)SSK$oc<0Xmf2gL!?@dnNO(MW0Aqg4k6v5b4jsYJLLEUf9IBPaA-i z&ga)*qItS`^*mq!_po{%A$OL~ZOqa6T*sH>8e>3}^wD|a(umuSumk{Qdt}lWvrS8K z%{)TxeBbkPbiTB(mJdg20G1_i7knNHP*?3A&fSWHB=U#=o$snBRxzr4gHNS;2YnuU zaXWEW9nS?NC1C?}zBi|E+)iI%a0vX(35ZHUfX*Kae($u!2=Jp2u(gB@)%io<%f`Me zfj?_dZ~xEW5A~d*%>~6EVMynX0bjZpRy@-6xZu}X1N96QM;*)>>P7VB7E?%=>UID= zm5q!6OpdvKf}f-dnv>LV62!+6$&e3x6kTS#R)Fvx?3KIT2R`4^unPhZ@xj0^DP_AR z?yR+-k$MMvr4{(VPa+duvYas{@nQhS9`2-s3%)`C>yetQ`Mbd9gtOk03zFdbN)BVC zEvpmhe)xOi_Lv>1*`@QlZVnl9oWEuF%ex|91e|0LUt-FciBMPl9^7TMQ(FMCof)p{ zc0$T6-xh?yJny7DP2KrjYr29kH~QUyUo8D z0P5;Ae+B|>-{vTG0Q{-TU9q+JT!IX`V=T}8n;|*IAuJ%4OPp(+Uq`^J6ZLT8z}6Fd zLzD+W80phFSg-YwY0Dl62$53gPpX-vUYZ6daRSW#m8GYYH3>Z_s7FKZD!Wv}^xcvS$`roaB zesv7+NY2NQB;8{7k1e?EE)Uoe=p|(6SJ#5}kOyP}R*C_AA25{(*eC|fB_R_KnS@*m znn?f=HN9W-^rv@K3rZ;llvM>6q4|AN5WC3(QglCu%mel$LyH5riq&RO57`e$g@nWO z1J)v8E)j?92c%{Rhv^5TO2VP~0c(-4R17#oKOiL%avrb{33HnExg5QNL@X09BL?Jt zK;+$@`vE&3As6Fj5|H}=5o18^2PEKravt#IGW75S%&86Ken3PLaz9{Y62|<~iQEr} zYzes^5SfJB57>Z&u`wX`12!fh=K&j$(AO`><>(zGVwr&H){*-Gv3Gy&2kd}^9E4{Q mkoy4C0000zR&~znA!6HOWwycfY$qb&ZelF{r5}E*`J}a02 literal 0 HcmV?d00001 diff --git a/xui/fairy/button_lower_right.png b/xui/fairy/button_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..f476acb0caa6a110fec4a6953d8082c6f4b5f6ba GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D45~t z;us=vd1}8SZ-apV%X1IWD_kB9r!!ZyWLa=t4dBdJ!J@?|$Gfyv@Y(j6r&Gftz9uaZ z3p(>;&5;b9nh&2Bi1l5$XK#`9@}Y<1X0=e>_kx!GRVM}FcII+4tT?Cb#`)me-DOgX bS#~g*2rE{mY;HOTw3ETp)z4*}Q$iB}D*HU- literal 0 HcmV?d00001 diff --git a/xui/fairy/button_middle.png b/xui/fairy/button_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..4106227eaf7c5feee9e5bfe155eb41833bb6e9cf GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@ALX t;us=vIXT6^@Avrzb^}8JhQrQ`3@e%$SJW)Ku?(n!!PC{xWt~$(69B>?7qI{U literal 0 HcmV?d00001 diff --git a/xui/fairy/button_right.png b/xui/fairy/button_right.png new file mode 100755 index 0000000000000000000000000000000000000000..1a024f4297cd7635401f19e4a7623ed806921a1c GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&P? z;us=vIXT6^@Avrzo_qI`Bd%_2Pdq=*q^++nlE;UK<-msk28IeIj@N%f+t&hhFnGH9 KxvX2ukxGI#zCn2Ed;Od4}#{kaxHq64zj1D`Q7*<4bvb871 Ry$5P!@O1TaS?83{1OT=RAjSXy literal 0 HcmV?d00001 diff --git a/xui/fairy/button_upper_left.png b/xui/fairy/button_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..0f84a4eaa1487aa2e41ff6ef9dcb1bd5d80b7c5b GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C>ZSN z;us=vIXT6F`Tae^Kkml#-t{%0#+RZH}~T@Y>L7mo@_v%#>UjJfQjL=ob<)YokG<>;~6|%{an^LB{Ts5 D<)tmm literal 0 HcmV?d00001 diff --git a/xui/fairy/button_upper_right.png b/xui/fairy/button_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..5f38191a6dbd179d3445136887518bb470c5df48 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D46Q$ z;us=vx%FHi?*Rp#mWTUK^YCzHI38A6uu$ki1B=Omm0~vz8?oJ<6nm-NdtZ!Jnn{~Q zdrxg>Z}M@S?Sh_~-<{T~`)PhxJ=o6YwMu`>hRSufO$D6T988nkqL;DDaU`(G|72y) XTPc^?F3q6=w2;Bm)z4*}Q$iB}Mb9@K literal 0 HcmV?d00001 diff --git a/xui/fairy/check_box_off.png b/xui/fairy/check_box_off.png new file mode 100755 index 0000000000000000000000000000000000000000..5e203c60d9ae0cb0886815f3c3baa9ed360004bc GIT binary patch literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6wL8- zaSVw#{Py}rK?X$*mII&Ly;ihF>2yWu9E{3&XkR%$*uU`H& XY69jAzm9wW+RNbS>gTe~DWM4fT|zw? literal 0 HcmV?d00001 diff --git a/xui/fairy/check_box_on.png b/xui/fairy/check_box_on.png new file mode 100755 index 0000000000000000000000000000000000000000..85e68e3f057f12b6df4cbfdb114db5faec9db18f GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6x{CV z;usQf`0ezAyv+tYuJwUp39Rc6aLsI8xW`M9F)X2_tfk0_spay72TP{D=|1|>-rix8 z{NoOO!Bta}+4ig#erJ1OLD9~)%z_7E(uxEV9>tmNc^zrCA&h(O`cJ)ooD!;_Z*LXZM_n zinEGg(GacU`cU&SPVM;Nban%tU&8YI5AW~b_4d)b8Nsmdn5@FLl$9|+FEDtz`njxg HN@xNA87gGW literal 0 HcmV?d00001 diff --git a/xui/fairy/cursor.png b/xui/fairy/cursor.png new file mode 100755 index 0000000000000000000000000000000000000000..56748b54573a14dc09feb5a57fb9bbf1d0197211 GIT binary patch literal 344 zcmV-e0jK_nP)+FzhGP2q+DE}OVO^GO;Rhy(0IjzTgD3^j48Yx3djx6$CIDaU`bbS*N!Qr@WtIV?ii^4C3M2C^nw`ixlK=2Cgq0`nYU5MvR_ z)|V~O4HfyIoT(c$d6P@jV@!ND$w;jQu$L*+-0WdjBSo!&zE4lqE)i6?+42y)^&aFl qx9CMnnJ-zsL`@mErDAFRg?#}n?{Y?-F4C|70000td36IRsTIepvvl z{SE-*SPns*DgNgt?YjH@JP1lkytT*gjoE)rb(vu}it`DUfY3>apXcNER4@e+D)c@I zBm}{j*S*64f2k0Zw0K_qqGK=|h*}6;$~dp}5r7k)Dm)jA zPZWNR`&|qI7uPUa^X|}b;-~2)bQoSg=ziRZUzV^i`aS+UO)seA_uzI*2ZBLR2)KS) z^L>Ki#Jfrw^X_2g`TcO8Teyl*02bZ~G?*O(C!Sv81HhU4IKG}m>&Ll+iiyX9xha6@F})%58tiifW6YsrL}4)-S9F~Cz~V#H?0abA4o~omy9@+6LizsJapI}@ zY`&A=^U@H!;v*2S6@(yo0Z0`MBRs)E54!4|6<=8{T#`e;w_l%IaiqWqd-dw@Q#}atuF~7TYSI@vH);n=b4ru+49Z}d{8c} zI+q#+m043r-0pS3^t(?^K12y7X zK)}01MHZ0L4@ihFhLGw1;w~U5{w#O6aINlJU(Xp0PTdy>v_4Lp@RiON_DV*3F372U zmngnnuP!w0z1@!cY45!@1NO;>#-~PifvGTV{ZRfx$IbnHJH#mvzCrx1Z<@k;o?UDK z1n(5bAk5eKBMB0r1dd_g#RH%enOK$xmxb}k6d5jiC6@MMEvQ|RR5gTkI+`P*^d1TE zn*~Tg05~sAPD1@@ z5P(!5++hnz@mT;;AkdQP9x(v4L-ZZdD-oX!AO;~;S{|G%5nlwL7D9_sD!v#1juXD2 l7<2OBX&NVdfdv%n_y^3ntyMRgF`(@rkxn_lCA?CFiYEe@E yfV{W02WA{AXxsMlf$d@2wm@#TgBlBT85qPoLjs;??7IOpn8DN4&t;ucLK6V%#5DQ< literal 0 HcmV?d00001 diff --git a/xui/fairy/fill_bar_left.png b/xui/fairy/fill_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..09c10c644fa4b787f710ce6982ca7282af391b8b GIT binary patch literal 381 zcmV-@0fPRCP)Uy>t zgo1e`O;k(yi2y&&cZLaxX^jsCjTuwzS~~jaJ)m`;b7R`pQ<}ZC0Q2^>nzikF6mB+3 zv)^Y?TZx{`#U6;ZEM-hboQnZiyE$iA;C0-QdUeAPs9gDf-UDY^i8rIH&EDJ)|sAEhY{c2`G6$}1) z7DR|BJ|xcWgVHRBOd*L%u@A7`2tiKATdwZX8MJ@Tr7(=nftoX(#e#hmdON;Vj;AZ0 b=PmXH;`4;htE^$S00000NkvXXu0mjfJn)<> literal 0 HcmV?d00001 diff --git a/xui/fairy/fill_bar_middle.png b/xui/fairy/fill_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..d7b6b15ea28edac4c658c9e525d754a9607a05fc GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9EHPk}Jw zE{-7{$KOtM6g*(S!P4(DWsTUD5a+Ef-X=$#v=^NJQt@=&hlFy8HU?WGwQHaFUKF32 zrB?ig?O|Ne`8{^74#{_#L^fRA{(gbw%f_VU{V%=W0a>qkV!oKN`TY`Vwvc~Yv*qm` Y)35IF{4JetfEF@%y85}Sb4q9e0I42DN&o-= literal 0 HcmV?d00001 diff --git a/xui/fairy/fill_bar_right.png b/xui/fairy/fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..8b0279b0c152e0eda579e708feb24f9b0ca506c0 GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eL!3HGH8OdY;Db50q$YKVDnWsRQ@$tkZNu>8hRRwrY_2^=48O_+A_C&ukSr`o!|(8Ob}7Hm6OTA-{puw6s_z^pX%mP>Xu-q5{3UKqoPHy85}S Ib4q9e0MDOGq5uE@ literal 0 HcmV?d00001 diff --git a/xui/fairy/frame_left.png b/xui/fairy/frame_left.png new file mode 100755 index 0000000000000000000000000000000000000000..315183b1955182102bf1fa47aa65b50c9d9d69c9 GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@Amg z;us=vIoZQI`N#e&(Zm1C-%I>6PGI!mVL9+2fPsNMo}FX!t($g0r3{{~elF{r5}E+& Cl^hNL literal 0 HcmV?d00001 diff --git a/xui/fairy/frame_lower.png b/xui/fairy/frame_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..c7836fbd124dce3972d75b9caca85d941bca5c37 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@Age z;us=vIXOXsso~>Y>$d+tL^iy+*?ga+iHl+JN7k!3sw>)o${0Ld{an^LB{Ts5q*5Hf literal 0 HcmV?d00001 diff --git a/xui/fairy/frame_lower_left.png b/xui/fairy/frame_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..f3c43c9364c3233ba71216a9928c2bcb900ca923 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`;E z;us=vIoZQI`N#e&(Zm1C-%I>6PGI!mVPTLJ*`QFo!BS*h!g)CxwFi?@5)u*^7|IxV VZf;taG6$%c!PC{xWt~$(696g~B8LC~ literal 0 HcmV?d00001 diff --git a/xui/fairy/frame_lower_right.png b/xui/fairy/frame_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..39ab611bbc2b9190b6b2060eeaeda3d94e0e6c4e GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`#B z;us=vIXU3~)1^xi|JFwx{qX;;b=!X*9u@{!kqvvQkAIMl{cz8gBP{_4ZflPT{2 literal 0 HcmV?d00001 diff --git a/xui/fairy/frame_right.png b/xui/fairy/frame_right.png new file mode 100755 index 0000000000000000000000000000000000000000..84cc10c957d7d00de851f26a9eca1d2afbec72f8 GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@Amg z;us=vIXU3~)1^xi|JFwx{qX;;b=!X*9+m?i0vH&o@33<;J1zPPRLbD#>gTe~DWM4f DKPVpe literal 0 HcmV?d00001 diff --git a/xui/fairy/frame_upper.png b/xui/fairy/frame_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..9cde493cdcb93708947f058c87d6a85712f7c286 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@AIW x;us=vIl1P0-$Q$5xdWTh`I(trx!PD57*a2?Uj22BdoEBFgQu&X%Q~loCIB*l86N-u literal 0 HcmV?d00001 diff --git a/xui/fairy/frame_upper_left.png b/xui/fairy/frame_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..a060d824c8975ca59466c9728f0514a9b8d1754d GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`~I z;us=vIoYPT?cx4OLd<>#jIza;o4dK?SPhQttrqABc8ro@Zk`~(th|d!jg6^+kBec> WFHSKliBdVBb_P#ZKbLh*2~7al?H*+S literal 0 HcmV?d00001 diff --git a/xui/fairy/frame_upper_right.png b/xui/fairy/frame_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..e0e41ad710a2f70b62b7b33ab87f7151eeb9f8b3 GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&S@ z;us=vIl1P0-$Q$5xdWTh`SU!*#cjA^Viu^KnRWC)hu+L-Z5yU_HZm+|W@7mIn)Bn) T+DrR^IvG4&{an^LB{Ts53v?v) literal 0 HcmV?d00001 diff --git a/xui/fairy/icon_frame.png b/xui/fairy/icon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..9fa4604d95f52e8f879b123f9a8895d6939f7304 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6s-4j zaSVw#{Py}r!3F~k)(h*Wd(LQ$l Mr>mdKI;Vst0CmbHGXMYp literal 0 HcmV?d00001 diff --git a/xui/fairy/menu_lower.png b/xui/fairy/menu_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..0a93d4b1740f3b05fbd443641282c017c5171157 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`;E z;uvCaIyuF_@Ar8J#)PB=0zFa&SqB~%G_*eaYum+>Q1iX7anYG0o6`AP;}%?DU^rvU U8T!U<1IP*nPgg&ebxsLQ0Kp_CYybcN literal 0 HcmV?d00001 diff --git a/xui/fairy/menu_lower_left.png b/xui/fairy/menu_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..848c900057afe09cd778180783d67f7cd3c3565c GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C>ZML z;uvCaI@!lN`N#W5hYmadVuchCvEqmWS3=SPfgUM?EQV6v8=Ko3AKsm5%fs{j{lpXo zWo97Iu{SVKc*+^Xb0Cf5B-;XMr)i7^&K`yg44J{gXAgH2{sdaU;OXk;vd$@?2>`7S BGY|j( literal 0 HcmV?d00001 diff --git a/xui/fairy/menu_lower_right.png b/xui/fairy/menu_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..4090cafafbe130876988cc000de217846c2712cf GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{D46Q$ z;uvCa`t4*#!2=3BEatKz2}{KmvGQg(I+-dglu}|;*|MI`X5rh(wP|VJO9j6b7&@Ca zrG+?(n%Qk)(*EFm;Ow~{Hb!Z+3vO+=e>&}ftx+4{R~xDs>XaL Xs$WrCLs`cjXd#2AtDnm{r-UW|q&qjc literal 0 HcmV?d00001 diff --git a/xui/fairy/menu_middle.png b/xui/fairy/menu_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..0019c6e4c96ccecb00f6974e27c0f65ed5a0519a GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@Aac z;uvCaIyuF_@Ar8J#)PB=0zFa&SqD}yHXmhR*crySzopr0KDlO A3;+NC literal 0 HcmV?d00001 diff --git a/xui/fairy/menu_right.png b/xui/fairy/menu_right.png new file mode 100755 index 0000000000000000000000000000000000000000..d7f2edb934c68b8220855193b7b73e1389d2f9f8 GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{D5&e{ z;uvCaIyuF_@Ar8Ju8R78#j~mW&E4G0Aj~Yx+?sHuA&}XPS3(D9lu9@2?};%-rvNoF Nc)I$ztaD0e0svVA9(4c! literal 0 HcmV?d00001 diff --git a/xui/fairy/menu_upper.png b/xui/fairy/menu_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..3cf89214f07b04f705f4b65dc5a08f95fbc265ae GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{D5&r0 z;uvCaI=SY1-$Q$5)`ryca%^pkrVSGvPqrHA8*pd^K4DU0<2ty4aWNYYA2Y-AQudDP Trbk`_wK90R`njxgN@xNA#62L4 literal 0 HcmV?d00001 diff --git a/xui/fairy/menu_upper_left.png b/xui/fairy/menu_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..ba4c0a75f998f5481bb8797e56096ce80584f46e GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C>ZPM z;uvCa`t3PG(FOw^*NfqNYz|CP69jaxHcZRvY{}|qiPFe^d4(bQ|Fnm9Cp&BpT45n} zOF4a&rfUF&Z&#u9(JmRA-*1_JwrESIr)^kK*mrt;HG}UG5})j#XJA z)M%)z*}$?y)X*f)e~0D-{bzjID{^-`iZf57y&7#VYL%c_xH#}72U2@I9ML_H(Pe8Bc zI<6RwJ{xtVhMP0b-Dk*5{}^QO%%+BgMZkf95k@$CbP0l+XkKgf&4r literal 0 HcmV?d00001 diff --git a/xui/fairy/scroll_bar_lower.png b/xui/fairy/scroll_bar_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..f4c77c117346e8c740294c32714c728baddd2552 GIT binary patch literal 316 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQk(@Ik;M!QGf#mqoo!v~l>|-*5^?3cHbG3M@%Mo_6P%wuE3u!+Ss7_2k)z~P z#8<$lz%(PU({jEwdynz~9%csSe^WF$>oi4}l#kv^-y^*967T7(e<(oMW2PzB!byiMCw@WNV)K?ZNkKjMVlj} zb7v+donia-q+!K5N8?lST$)-Jwyv@9oSgJj?Vw4i&g6hOrR$rPgh%Z z{8sY}pREhuZ0}s)Qh4RBSkvYss_!RGV||%(b-uDd*XsUfynaz-)27e56bke?gQu&X J%Q~loCIBa>ejES* literal 0 HcmV?d00001 diff --git a/xui/fairy/scroll_bar_middle.png b/xui/fairy/scroll_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..d627d82e7d56b23f20b1b77668401e46b7b4e0de GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwEvdd*`@d!H%WV%n hY-D7Uc%XlPb)GJ#g5{T+sz75HJYD@<);T3K0RSNmEOY<> literal 0 HcmV?d00001 diff --git a/xui/fairy/scroll_bar_slider.png b/xui/fairy/scroll_bar_slider.png new file mode 100644 index 0000000000000000000000000000000000000000..1ae30164a4c3f0ed9d4bbef3d2bce22cde80d2f8 GIT binary patch literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jPK-BC>eK@{Ea{HEjtmSN z`?>!lvI6-E$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a z5n0T@F!K}$Gd`ZULQpwJ3W7sn8f<7cN_d(%--*GJHVawL*KNeNiy$jvw8gpJAs&u2}&W<4S z@3)UuX6~rV=;fN(u|wz7))if@bHu)$U1T71u3j@~V*Ux!_x-MxlEDX+`jW1`ZFgNN clzfp>P|Najpu|C-lNlI1UHx3vIVCg!0IQUE(f|Me literal 0 HcmV?d00001 diff --git a/xui/fairy/scroll_bar_upper.png b/xui/fairy/scroll_bar_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..fd83ff9f8d8cfec6d89fbe851e17dfaf3960c155 GIT binary patch literal 313 zcmV-90mlA`P)q$gGR5;7Ml+h8wAPk1TaxUNsnZXe-YED2^j&)jp1WiYCE4gP|D8Jij4m)_#_>I=yf`_pBa;6CtW5_gCGoWwxbo^=5Hj zqo1Wv)F#f1A%v6_zeK@{Ea{HEjtmSN z`?>!lvI6-E$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a z5n0T@F!K}$Gd`ZULQpwJ3W7sn8f<7cN_d(%--*GJHVawL*KNeNiy$jvw8gpJAs&u2}&W<4S z@3)UuX6~rV=;fN(u|wz7))if@bHu)$U1T71u3j@~V*Ux!_x-MxlEDX+`jW1`ZFgNN clzfp>P|Najpu|C-lNlI1UHx3vIVCg!0IQUE(f|Me literal 0 HcmV?d00001 diff --git a/xui/fairy/separator_left.png b/xui/fairy/separator_left.png new file mode 100755 index 0000000000000000000000000000000000000000..511455c908cf32b18966a0fd0726d104c88921c9 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwsosiTN-N%~6+#GOJl8wz# zm525HsaA;(kq4Rzp3C_#Pl-v0OSrL_eK(`e6gDMpuJ?a!*FVdQ&MBb@0P)2kBLDyZ literal 0 HcmV?d00001 diff --git a/xui/fairy/separator_right.png b/xui/fairy/separator_right.png new file mode 100755 index 0000000000000000000000000000000000000000..1f97a939f127d4358b4811d5560d0f658ab95094 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}Jwm!W? bObiU_+MJU`+0`EcObP0l+XkKdu=3E literal 0 HcmV?d00001 diff --git a/xui/fairy/status_left.png b/xui/fairy/status_left.png new file mode 100755 index 0000000000000000000000000000000000000000..6bbb1df0ea66454c5ba783dcbbbff61bfaa64e89 GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9F3${@^GvDCf{DCpto z;uzv_{Owso!2=2cE*JUv91dk#a4u(^nqkT9;i2_nrsuA|#<$;TGo;xFZn$o{Kr(!7 u$`Kp+cN08U{+YwT$i%`Spx|)8eD73oE`u4tydQvOGI+ZBxvXLMMsS8(!4dFB zMMU~dTjM1r8iRc(cW+eyK!n8@V111vipupHB2b}gwC{`iJ#TRrdY*yn6-x-=1u&yZ z#Sl#aA^=es(R>GD2rq!hfQS+o5r}XR;(~@Ha(q9}cIvtSQV>l5%yx{YDUQ%J7PP%$ zz^~3VW<$h6P1m~X5TXkpgvbJHTgL#>N709fmD(=c4y08-j(K^IlMM$zE5!aYA5KjD zHM5G@&gZ_9-H&4u0tUiu;K1W>XM#6~UWj+|tOyZ4+z|!>$ee0i?MbhsowyAQJkFh3 zmq3K>cA`}kMX~L0sRGdXi+^rO*>n^GzGJmCtcn1xUO1DOSpe7KDLGLE5SoG-2p#!1 zqXIB*PUMt2cl^4~j&1-SqAS3K=nnWq{0y)n@Ne}5or>0^S2L#f00000NkvXXu0mjf DYHp@S literal 0 HcmV?d00001 diff --git a/xui/fairy/status_lower_right.png b/xui/fairy/status_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..803609ee0c596b22cc1450e890a0017736565136 GIT binary patch literal 405 zcmV;G0c!qb5(_eIY&a|7GV2}wj{s6$*=XE%sD)BQ!U?>NlCg6B{|Lt-qgQuh^2T#R& zbP46)B3~BJz=sKF;mf@i%&dZl2t>AxcR6@Yq&2($gaZKO;LZWlG){(q?R6fqhKnrg zx#at21#*QFrd?!t8$ICwK$_(=3a%FLz8)TyU}}z30zKhjjznM{Lm2N;%r+9}2Y2oX z|F9S6fNr+HEI6@L!C#uNDr|v0SHnMU$C{kxGq8V$TdRXN3usP2>wz04APqfDJ>aRW zcDO)*$93-97X;SR9+z23ZBQ#beEzLQ)re59hT9U*)I60=bxFx+V!}TkZF<51z+A6o z0`UQ*1+LzXQwNk*c(s7{ec)9yaDM|`;6ITYTG|%XV%%wAAih%j>6kQwv*9 xYdx-X2(*cBVB|?)V3s(*z-9nt{9=c;3-;ndn>_OI8chhA>B0&3v^fF}V4yA(9R0W3lQ z%#?0jZxuUSw&0^%uU0k2t5X3LWL1uyLf^GJBjf-;YUtFGfb-Uar} zZL&=}*^2)K&w79iU3-2`NDR*kcs$x5@v>3_&k6`(?92ZmpadT- cpachiH}%`_0RD{+_W%F@07*qoM6N<$g4}1Cod5s; literal 0 HcmV?d00001 diff --git a/xui/fairy/status_upper_right.png b/xui/fairy/status_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..24c00a3bbe0fa642baa8c1ebfa268440614d106e GIT binary patch literal 475 zcmV<10VMv3P)wXvxnsd3geVzB(ejq?@co*9_qKlmkptJBYy;`KHGMm?pehKy=Kq z3@G)zx5$LJ29#(8_eg-lmd)7ejLNzLn2D$APP~_HG`Dc!RvMz>h~+qp`F2GPqAy9)nGpTHa@k;=2~jkRT!p(L z)0Q^65Pn&K=d1TaOmct~8Iol{odHo~NZhb702~C9g|1wHQ=l@BDi8hQVJ3CfGII6c0|7ru~FOPuUX1UFA#qL@FC6wcmwUdD&o`H RK8FAR002ovPDHLkV1k47!XW?v literal 0 HcmV?d00001 diff --git a/xui/fairy/tiny_fill_bar_base.png b/xui/fairy/tiny_fill_bar_base.png new file mode 100755 index 0000000000000000000000000000000000000000..763dc2426f7c768383d6a81d7848294a3ace649e GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg`npr$CtT@x&!cK*1nS z7srr@!*8z~XMef>XXm3@uvW<^7vl>Ka#F`o}nF{(r`=OlfIlj8aWYZ!3RM`3p3i!PC{xWt~$( F6986aIb#3- literal 0 HcmV?d00001 diff --git a/xui/fairy/tiny_fill_bar_left.png b/xui/fairy/tiny_fill_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..1c94cf9dc9f15711233c864fc0f6a0f476a3d638 GIT binary patch literal 344 zcmV-e0jK_nP)rWkaA!OBQ-2y>tzUHOL@{62tf>RpL?u0H(hK1 zUpWUtYe1=lI*{st!0932dLU%EpB;ytfj#Bd&jM;M zI4lb&z2N#;u-6Ob5EbhMbEf=vFCYQHD5-oE;PHx^OqPR; qbCI(lmwZ`JxbhpbA;d&*2Rs-iA{Tu_e5}Ix)?Dw*R?}TJ90`*BJ}F#Us3T zJIoKRZd!J(;SOUZNA literal 0 HcmV?d00001 diff --git a/xui/fairy/tiny_fill_bar_right.png b/xui/fairy/tiny_fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..55bbe08f7fb00c3ddf53ec87cb53bcb9e4e03112 GIT binary patch literal 353 zcmV-n0iOPeP)0v0}Y)pMb+WWGNO>-=Dw_n{+Hlnr# zn3rorm}>56H+Acj4Fh0I5Re3@rJi{oU{7%r12q6R2M}#vc3o25h*^*TH2_$fR#j^4 z)gcK`oVplg-^+lC2vbRo5QWGYVKc#Rfa^@e0%wMjx1f7FKa325hjZ_pi$MK}Vzf37 z+Erb$*NwcJx>)4V0cNPI>QZ@^0;*Lf1#Cd?TG2XEqWRzwzyeeXiHA!7hk9LfOw?3! z6E-DV@9V~Sc1)xsU;EE+jtQHR@Yg|?{l7f`UFU^V5hsob00000NkvXXu0mjf5$B3Y literal 0 HcmV?d00001 diff --git a/xui/fairy/title_bar_left.png b/xui/fairy/title_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..daa5ec8362ca317a6e833c009a863d6d4abf37dc GIT binary patch literal 554 zcmV+_0@eMAP)=KZ$z&O!NF1hf3dLRKFfN93SFYGi#7(mE0SNuE!7*oFBILbOhbHyXBzY??d z|9^WNGLA%mt$1m3E)GU@hAtIPjl?w70VkzUO1yLXQfF)47i|P-fSh<^EMbwnvJ&yx z2;{_1(;YCA7f8q(iS1Oy#9O;hd`r{Re3KL}vHwQ_g7>#YXYIP*N_zhBXdD4)+grHN z8ffMHLu#Ps2>_o&lV@f!T8aJ`w=&91touh4v1St%1-ry=41*XV(e9-en^Yj*rzNaGlnMg`NeW zx)T3doDQK<_ce!zXF{m-bx4Emmb$rE@>769gu#2+5tn5P#)V!Cz>h17fcNXUwb}Oh z7lJ6huTdgEFvRya3oXbJ{{lF?4r+Ab=5_G(<8&;I&JcyqI?$Xk3Zw}1451@a=-~Z& z{kn7pWNs@KtOLM-$j)hRG#V&tII&)(6N_gdO0C)ZKn{X5Ek~YXo7_%QAi6AK s4n(OnjX(^d`0$1D0PJ_#-afZ^0=&jON$oQ7(-+bv6K4=vuTb9PzUBdvt!TM4?k z&1TELb*{R_ypw6?$+h2~7jw+`ZSaEa&#vj!0aL#?Y-qatMX?yjD&z|JV#qb+iy{}- zjj)TyeKt+HSIhEu(V1otJpEbWd-ENBy%pjQo!bPZ1Q)#px`n~h)z4*}Q$iB}B%o3C literal 0 HcmV?d00001 diff --git a/xui/fairy/title_bar_right.png b/xui/fairy/title_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..f2fc8b1ea5cb7f1b101ce9a6e18d5dcb8310af8a GIT binary patch literal 288 zcmV+*0pI?KP)nw?}H>N@o^Rnz)1l9XuqQZFz2VHQ&R)hwOu(x mIyAriO}5IQl*;@PXdX}K7)gG(!Ounj0000EamTas2I6N8ZB*Jg)Iegd|v#Ia(4lT9P<`s5KBs8ccn2!Sn8t(wAG7Tvqu#NoL=l z6jlE+r6~dmEDc}3$Suoca|pEzvQ&@z8hBLj*&){lR=X0{J9-KJkcn9xyTIcGQyue^ z-)nU%RMVrI^S-8_Rzkng88H7RyL!xEamTas2HxN8SSlJj`=fdGL8};5ocO#M^M{A-06~XD5c)PxgN=63TZ$H91N5J@caBDwHYT f>V5IO_XV5v;>h^96HUy3wla9S`njxgN@xNAX*fV* literal 0 HcmV?d00001 diff --git a/xui/fairy/window_lower_left.png b/xui/fairy/window_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..599be6489c46060f4f2857da0555e9e2398ff7c2 GIT binary patch literal 992 zcmV<610Vc}P)9~x4*2l#@e%MJfWM;4;0Kxc`#DUC2sdzV-dhuZr9ng%RS?8< zHECPin9)=LzzVc8z5G7+>wRBo3MgfMxs>N95HYo+wAo*X0FebmiK3HIz~*?ah^Vdz zmIQ(bx7<;6jQ{d5h*yXo27oBO#r6Z9!~+;)KbkJ3fE+cU$jy*T{KQv`;&ar5;`#w8 z;=9X$?$2LnZ6MfXvf2np5$~%B)dENs@2ClDQXsGl5~P%1W)RW%?A|!3O}qUy;^(ig zErN&8I)T5bpDhKvdwh? z$PA%Q02v_^T>~WXy$J496J9wQ-@U^24iR5hNHGB?3Uofi7zwt6ikCY&r9)`Tx;KP9#JgrcxC}C*(b|}gc`>pOx=uf(gN0zzK@vkT{ORCXB7-Z= z3q11iTj>4}PV`U!Z&BS(d~{av(`!xdPuMd1A*&s6I*i8H;xL3<;(ZWy z+Y7{prT=7i%YU1`do*de8HVuV0W3lI2mn6~!s>$v+ei3V02V^+0R92mfW2oEkw$s| O0000loPlVCI&)K41}N<2w`JT2zx0g1Y%GK zn*#U4%%L;Z!}jQ5I9F{gwP54^G&35twF7!Q)Yl!q2>5*&h;Ua5Q0noP0?y}+mtDBd zh=U%t+q%z(pdA)~wKCT^;lq!QkAVLGdK5?Q`gnnRxT5RmHJo#g-}YDlh;a8S{MIRt zh!|BAM3)h8z2*z#kxqZ^AQ9jk25ZBi&xbJ+C9S`*Kpd(DIETSciRF=1A|MVs3(RwT zD~M6{rl!&IN3eGgqonxnZ-59mpK-4VAqPZJ04(0Q>F0K910e>Y7yw_q-=(#LP^}N( zoHypV&aMT)TGO@_p5^>slc5%brhY&m=c__!<_E-b-rD6Gz38ASU&<6y9)*8+^Z^{crtO4L;YQPLaH0Mj!1R{bl21FEXca1U7TFVu|ULX)r z5<*J6NGI4T9sJOrLj3hei5FW7w1(iEgPL8~W>!hD=K>|uAy(tIIzi$9NYZRM2r2O-M5V~1F$oB%k%C7WH zB0wS%mc(=ZGlZonu$u^wh=jR#zX)1ucZshCU@L@>cy4s|imwV_Ed;I0i?0q~4Fqe; zi?31yLq}+x!t0tE;+p_i@)W)3c-U=q!~?)s+o#s-<5a(7^Td`Jy1%C z&uNuU?<(H!7`u&tQd1qD&z@imLQ?>|u<^rGN<0z$10m!rMR#Kpsl^Idq)4Y;K?^LTg6{4&z)?C{eJ-o@v8vr8U32#xxva2 z-^33nDL%AkDI`7{fW+uqp^nS%8|LDd_AIfp6ngGhJOZR1U_6@|J8PZ{BKs6!ZG7wQ zspRNOi4QkVCg?A)vy^(`JoY~Fp=-v(^C~mvar@BY)-?%dDR-~I@bhy#04Zl_%|?sn yj*zsuvUZor>6693O$4N-y0EamTas2JnK;FX&0&Vt_q-L~UZfLn|z`9MNwZ)MBUWZqa^w`L90< zN4&+4B1Q&TZu7?DwjBW>j#IBsa_YJ8U6~>6*t92eew6tgKeoh#;rGG$H+e)Zsy&c( znCX7}z}&95EamTas2HxN8SSlJj`=fdGL8};5ocO#M^M{A-06~XD5c)PxgN=63TZ$H91N5J@caBDwHYT f>V5IO_XV5v;>h^96HUy3wla9S`njxgN@xNAX*fV* literal 0 HcmV?d00001 diff --git a/xui/fairy/window_upper_left.png b/xui/fairy/window_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..b0d76b2571309b98da60536de4b2aa711665301c GIT binary patch literal 969 zcmV;)12+7LP)xne)IH1Fdzj2x!)v=Ut0Bg(o5?rLs$ifp@KbXtW`Ctq0KS6?i@YYv19A z*Zd+O*C@I2K>-3!G_Jl#Fy3Wsd+BxA|@OzGS z34RR6AqCdJo3F?F@!$8NATg`|A|M1$1l(>b;h_P34_`x%;u4}GAS?X0=M2F1O+rkb z$EK3CnD!*Q{F3G0|e`U?C>ye$1}6DdX)Eul{Lw$Z_It0fGPZZ zb#lVzl8|&QASobB0#EchNg~PyKZmr|9J>k5SAV*3$fR?_%YRsFaAar6TMAFZvIM+b zp>^F@VjnSr7elVxG)!6Hk8Yy0OJCS@WtRbd@6J-2?Uypa@7-ByYlCNwZ`Eht1AaPu zlmJaUZh{-&hYpXg@loknU`fJSc&*2dlIxUb?eO^#x7wmpKohTqCmJDZlaRaztbw0H z)+C|H0Y5L6T=2C@Xj0&{*09#j%4R=&jS`X~fSF$;tbwmhLXrUK+zb+iTTi~uQV8-$ z3CWe<(w!jbFUXkhmjXGq+`XUoB?_e`$B+1$jsnk&3o|ZDD}6*HG^Ijo3O^}%tCNtt z35Eo?kEu(->OH{K!0dXmGd^$9- z@N)_A`^d2p0x7`RA9txS9lQdz_UdJVdrG+d=>Ssb@GDwE8>-d!9-Ae6^KdKvcYG(g zMP*})gihbRMb{}KAVz}L@$l6O@JVpwJgiOYCVK^F{a7q_=Ut%U5*#_7S_pXs$U_BN zMU<3~Bj;BOAX3$cm`X^^`3(Z33amqfNJ!23&8NYdM3m?Vt*!%>M4WYOE`)p{0*#Tr zR+Ohqfu$T@wR5XSk1qoFcAf~> ryB|=UfTJ&l_8JX7e0+Qae7u0aCfa*tQ>k~}00000NkvXXu0mjfib=m| literal 0 HcmV?d00001 diff --git a/xui/fairy/window_upper_right.png b/xui/fairy/window_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..e6761a4d5d06cf65e3a07637a1cd816f846ec788 GIT binary patch literal 1060 zcmV+<1l#+GP)G@uTVzt3>|?P7@;#T0yB67X3z-D z2q)XVd`zfH4+~F{_J=F)$4M-FfGRmFQCWg$v~{N`*e(Q$VWNIY-j0%RlZzVt=n5$B&+IAnQ%PrMY) z#Q*@n=>`8>AdnqW|L1PRDxrfAvxDx=Gc1?&+Uw0zyY?Mu z&?~C%4eTAwyCT&0m5n}otjfoud^A3s1O9~v1mCasI{F)4kPINS&`_)KFp#>A^5x(i zz7wR_zs~`Ow~7CRiBS-MTp)cXqdXwLO?*N?y8>ju0i1FFimp@QaV!V`u@VSOJYqor zRY1rPpPU0~_>!D@k4YY|t95|D<8K(A-~qcA{{RFPfGWg$Abh66sQ?h6(M}<2Gn&%N z>J!DX_;m@nvWbv(O8*Ig4}kR}@9pvc#lJ5kl-~v`$peY;{|SK*0ACpF-U}38hCUvU z0-!1{V6Vcy(YLlM=K;Hekhu<^0uXv6?gm0cJmU7~t2|)05H`fmg;HIy^#C1&R1gnb zQ$l>|iqIy6BoJ2-Y7b(=+-baQ*r zhMR%8-%xEbiJup6`UL`RWX9x5(HI1Ng9Ku^jsYR@#@tq$7YITyS*$3VyFCe}lHM(E z$lh(W^%*U;=|NL0t=()9ig^Nocwbq%su9Wsz&*hyIA^;|%4Q2*o9s(?w_FUso>!qBUE4^LBwF>iuQrL3Cx>|6x%iz1Ca_Ow%I~fd{MH? zwc`5*dC5%-MhXC5vej9hQT2w#uh$i7y%a!6 etI`AZ2;dJY_5wR@XB>F|0000Wel%g~7ghH!f;yTE#uf~#8fI3iPRS@-5)J5h4RjWR Mr>mdKI;Vst0N@x-2LJ#7 literal 0 HcmV?d00001 diff --git a/xui/fullscreen_on.png b/xui/fullscreen_on.png new file mode 100755 index 0000000000000000000000000000000000000000..5d1c0b303c45fa79e56ae7fe137cf97bc34b3830 GIT binary patch literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6zuhM zaSVw#{5I?)?*RoK<|&*v>fOQ$>}x|_O}!AHEK*;2!=g`dsY650pMo~~9q(8cY<+er zE_?42?KgrQL6zqB=7_YfS)y;bs6WAzamGQ$0M<7r*-e>mDMgoaZ($8%o0Ptc`PH*2 zjM{0da$oMb`*P>D8}AI8YIq{`cOGTbnAE4pw5Q(fvZ&zSU@49Z8yR2f%PwN>6x|DS O7=x#)pUXO@geCw+3Qw;9 literal 0 HcmV?d00001 diff --git a/xui/gnoll/button_left.png b/xui/gnoll/button_left.png new file mode 100755 index 0000000000000000000000000000000000000000..9b460c64949ad46f9052afcbbda9a58f3be471ed GIT binary patch literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&b` z;us=vIXNUK=-2usOO7l6;tlEN<=9l)s(DT{bT%?b$Z;{m{AVqlwSK-NPy>UftDnm{ Hr-UW|+a@2L literal 0 HcmV?d00001 diff --git a/xui/gnoll/button_lower.png b/xui/gnoll/button_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..ac26ead93cebeee975a87adac72a88400a4af686 GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&P? z;us=vIk_Y->Bsp7b^}8JhAG+!JC84DiEr%g=4KRrcXzQ5BZJ*-j@r*Qt2=-?7(8A5 KT-G@yGywp%t{)o! literal 0 HcmV?d00001 diff --git a/xui/gnoll/button_lower_left.png b/xui/gnoll/button_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..e4e42f1c881d3134c93b31bc60f6b662d5cd163b GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}{2J z;us=vd1>!P-U9|ahi5FB{y}X1+vqP|yVzKJ_?~JAUJBaYX9XOb49+&d1Q+LQy|8i2+yc)I$ztaD0e0sy=vEg1j+ literal 0 HcmV?d00001 diff --git a/xui/gnoll/button_lower_right.png b/xui/gnoll/button_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..67b09868cfa884e49b080d4ba6d407554cc9ca5f GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`#B z;us=vIk_Y->Bsp7mUo64h8miVALiLsOU#hqU^peZ;ZAbEq4fuj9%Xg@aBpw5hnhm+ f2F*h&8Q2&!c?37+Oq*Q=G=;&_)z4*}Q$iB}$}%U$ literal 0 HcmV?d00001 diff --git a/xui/gnoll/button_middle.png b/xui/gnoll/button_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..58f49edbec231232426f1767f70b22798a17ade6 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@ALX t;us=vIk_Y->Bsp7b^}8JhQrQ`3?;uAORaexJprm<@O1TaS?83{1OUSL7jXap literal 0 HcmV?d00001 diff --git a/xui/gnoll/button_right.png b/xui/gnoll/button_right.png new file mode 100755 index 0000000000000000000000000000000000000000..44aafbc20dcaa285d28dc2588267fe352c310c4d GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&J= z;us=vIk_Y->Bsp7mUo64h8miVALiLsOU#hqXn42~sCYMPY0!nI|ADF*JYD@<);T3K F0RT4#9h(3E literal 0 HcmV?d00001 diff --git a/xui/gnoll/button_upper.png b/xui/gnoll/button_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..7a76ea43cac6e6eaa91e9e262d6633e373edd0df GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&n~ z;us=vIXNUK=-2rM_6<9B>@au`TJZj!EtjZ<;e+r4M;sUe)-fgTe~DWM4f6w)9W literal 0 HcmV?d00001 diff --git a/xui/gnoll/button_upper_left.png b/xui/gnoll/button_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..82f470713fc807ba5b2562c232799a9742162744 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}{5K z;us=vdFdHLUIqn$0|%S}g8mD|osMqoZF!iu;PX=7xiL}%fgs|}21xR_kt|M@6ft2<0i4{Ht zD`eqz!%D@r4z0WJIBbN!Wz^7+1@DgH$FUC+3 z;sLivh!>od5KlNGA>MGUg!}@ok*I)qKYvDZvLD-9b4<+FD=0{pdi4dFmA8-3OQICM zx(%%o8u;dqh?UU7cYnoN2?l<67?nz}@S@}RNCM#DMHSJJM9Mr|Rg!H^@R9M5sm)#YDFbqb&xB)A41s#DETmeVW5nMq=a0W)e6*7Vy z0UwYb6=?gV=a{#`fqQ9blK_Tr1v*!t!#~0m=-LY1^K6q47Jfeh>ico&fI|(aPk*0S z;X|+zk^^p$kX&$9LUO_xiJb+m9%%IUdZR#F_0O7SAOx=;(-)VHn+dVNueW}DIq?!= zfx9Z$VxEq)q^Nif`xA$#jz6eqc{~FOhz#hLo#CEQRz4&0r2psiYO$Z zo`)xuWNQ+O+c6TJT$IL0q`;}Nd`lt~PB$h?5)9nbn$0CxI4v-ja0L&~(ji;h^B15R VR)t6;6iWaA002ovPDHLkV1oKskr4m@ literal 0 HcmV?d00001 diff --git a/xui/gnoll/cursor.png b/xui/gnoll/cursor.png new file mode 100755 index 0000000000000000000000000000000000000000..954f14147bd57f8790e4547a9db125c431491962 GIT binary patch literal 396 zcmV;70dxL|P)AsvCC7$IGO5iToug^rN^ z;7}Zbagv@TR7I8F2l&|-^svI0L2oe9e+~d3{*-k$9tl>Cd&LIFjtbC0i==%_-?Q)*BI?2?)Tu7fTi=fc);yixQ4yslz@Bj zQP{h7e7?&17eI|V5T7rA5CX&)Rfv^}s9KQ-i0JwWT1ZcPo(dr64D&Pwm?{!*a|(Aw zE3OT`)=7q6LkmH_7nde&Z(|j5X!{n@HjxC7Af`9q+Js(*YB?2RHP36}QlF>~P8|`M q&OJapr*7;}gWl24zHU5+e}4cb$?b1BRX_g#0000n2z@Jfgk}X+ z=m>s461kM{AtZ1^eNImuH+XE#j0}P zjWOVy`v%^7KP7l;ZPuDq4*YMsawIG%@awt)007?4>IyjecNYlnmy`wU;Ege0t=);3 z`Et(fcv9|gN|}A=>lh1WHGAjWL+rXg-vD4)0ALFPT*?JzjS1+!2^ZM!7aV;gASNOQ z-d|VHXBjd6dLz1roScjl388!J7Jz{*B%%cV!vefIzViOM!uuZp{UVoB(*;RL#Rmld zdvwPLUyAam`04>Z?AIuA!28cWawIYojy3{EB5H~Q@Ln9t=p~0sf(j#l$pTV}x4t+h zqn8{G2@jcI$^uG?Q(s(@(MwJ%2}&|*)E84_^pev;LX`l0Ht_e~O(;kClF}FirE*eo zsWZ!oVkY`*V7)72G>wE;cl&+`yt{sVj^$G2UkC+vw#js()Q$N*1@0Z9@(U9l4Qc%-FrIoYHF#>F8a2VP2o1U#F7RuXF9 zxgyKxexdj5_0c6lz>{2!vRkvL9zm5PlFQhZ;g6hOqdMS zlO?VzoQ@p%3sJ|AtkEQ>XEOVra0hi1_=};r!P}a)lu;z8BS*eQLJs^$64cRVpCh3L zeiRAn8GZgp5=a&huG>?|Nbc_=FMMY%A)@L;stDDX=C0z{IY`CwTGC{a1@t5#=j+s2 zq9^#KS)d0AwLn)Rp*Q&EJU~JMHOl8m7y-U}MQBt^7zLia7AVyQOS${o`dr{etHD+h zF6Q~b53LCGDs+wnKfEF&Ep(PL%%`siNei7lHd2QYz}fH|RX~-HphknIk{~Uha!F7} zfUl9ztAP5W6`|CKQf3EAwC8Tkcg+J@!PB#Kr)4j)`wKm`F8%AQ53F%%-*8wALHk8Ynhv?S{|c z)?+i>k1^%}k1=L{9>##hd%wkgg7>p@iN!sRINI^_cYnUbv%nJn^Q@hs;f3u$kvr^d zbE$UHZ1KuWz6K51Un%2PrDt QN&o-=07*qoM6N<$g0IQx9RL6T literal 0 HcmV?d00001 diff --git a/xui/gnoll/fill_bar_base.png b/xui/gnoll/fill_bar_base.png new file mode 100755 index 0000000000000000000000000000000000000000..5456dc3f2024f0a380fd322947258de6ea140948 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9EHPk}Jwzopr0F4AH6#xJL literal 0 HcmV?d00001 diff --git a/xui/gnoll/fill_bar_left.png b/xui/gnoll/fill_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..ba693f68800237a1365b89ea250fc8037136a7cf GIT binary patch literal 681 zcmV;a0#^NrP)0eUz7_Fp|9!C&vwid&=O ziAodxb{55m*9VQv{ZR*Ajsx;Wb25n($H{$ZAKc(j>wl;>JQ+i(c%$JfeyUVnydsaWy^S%2MU`-hjIpII;IQO#_@;9_Z@#CJ&_yUnlV~>w;{l^Hmisn@TRqk`>I~8 zMq3MXr{r(~(1RBnnjD@;-mqr}M3nYkXf2thzOWjK836~1|O5LW5-z&5$%Dk z<8PiBUoy6FK;Kt!3~3y30T(($Gz|>CzFzA;=P@t6xRvriPOHO)rlVI+gza05ttGR) z<3#^I;630c>}XoWuzlNO;TZEaFtZQhuCwa6a&3-JES=8{X_Ze!yUfZo-mMnGFUUS{KbarcBAmW)x=bJ-C8( ru~<)(fsD?A%E%)YQK@|YwS*b090U!vURml4G?2m5)z4*}Q$iB}TMsY2 literal 0 HcmV?d00001 diff --git a/xui/gnoll/fill_bar_right.png b/xui/gnoll/fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..d5ea533bfa4c34b01ad935d168743996209f5242 GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eL!3HGH8OdY;Db50q$YKVDnWsRQ@$tkZNf}+p?CzS>k3xiY%4U@mu=X+OI-1ar{ zWZr%wKrr#;-=;hUkF)ID^2@y^Busz6#munqX?a!cKDRTKjgj|ud5VX&t`d8lDWs#+ zVJPMr;-&anLCIkA<&#eXnB-lnAM5Y_V&%<{P@MLoL}t}3ui!sy?|wguyEvb9;kVg0 Z8QsKOSpua+tbk5r@O1TaS?83{1OPXmPhJ23 literal 0 HcmV?d00001 diff --git a/xui/gnoll/frame_left.png b/xui/gnoll/frame_left.png new file mode 100755 index 0000000000000000000000000000000000000000..007b90c40ccf366306884378776f1f53c7781d22 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&n~ z;us=vIXNUK=-2usOO7l6;tlEN<=U#hzcVyaU{qscN~q9aV0f{MU0{j1?M0v#22WQ% Jmvv4FO#midAUXg5 literal 0 HcmV?d00001 diff --git a/xui/gnoll/frame_lower.png b/xui/gnoll/frame_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..41c176eac63101ac0e3a09af1201dc9b608ead18 GIT binary patch literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&7+ z;us=vIXOY1;=qa}OTNg@XA%<^7vH0{;m+>zej`?fKZWeYor|o+fNB{$UHx3vIVCg! E0QXfK6aWAK literal 0 HcmV?d00001 diff --git a/xui/gnoll/frame_lower_left.png b/xui/gnoll/frame_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..35e703caccdbb66b868d74f9fa5d566cb779db42 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`{H z;us=vd1>!P-U9|ahi52F{~$L1ZS)tfU1F>~d`~q5F9r2?d6iF2`S{>b^Z!G2?5`wS jSIrWibVfXwvw(St5MS+l_5(M81~GWL`njxgN@xNA-03VP literal 0 HcmV?d00001 diff --git a/xui/gnoll/frame_lower_right.png b/xui/gnoll/frame_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..ea819a5c14ae14bffa70a2ac69632c788bda8a37 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`v9 z;us=vIXT6F*~`o8|I{f{B&GoIw>LKrA2{N`5U{Sn)zkB(eH^Qvo}NV0_jh-lH5{HL e1h)h;@-Q&?*b0itoYMr^#Ng@b=d#Wzp$PyU=qBI* literal 0 HcmV?d00001 diff --git a/xui/gnoll/frame_right.png b/xui/gnoll/frame_right.png new file mode 100755 index 0000000000000000000000000000000000000000..6ed84463e793d58637b85c193b8eab9e95e925ff GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&J= z;us=vIXT6F*~`o8|I{f{B&GoIw>LKrA2{N`z{AhVpcuna`mn7^9jKbY)78&qol`;+ E06$6{D*ylh literal 0 HcmV?d00001 diff --git a/xui/gnoll/frame_upper.png b/xui/gnoll/frame_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..a885c775810b0c3e3e50702d8dc57dd1b0c02778 GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@Amg z;us=vIXNUK=-2rM_6<9B>@au`TJZj!?I{r+pytb^?8Ur0e(nY;W$<+Mb6Mw<&;$S# CDjmfD literal 0 HcmV?d00001 diff --git a/xui/gnoll/frame_upper_left.png b/xui/gnoll/frame_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..aee9a0454baf29834fe37988b45e9b402122e37f GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`p7 z;us=vdFh#rybKCFM;zDV1(Q_t8me-o+Y cm;2kyd*Th3gwcPkM4%ZAp00i_>zopr01uxfM*si- literal 0 HcmV?d00001 diff --git a/xui/gnoll/frame_upper_right.png b/xui/gnoll/frame_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..2bdcf7c5729227908e45efbb27fb0cb181896e98 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}{5K z;us=vIXNUK=-2rM_6<9B?07Kc&gOJ}=F@wtzi;r;($sYHIk1dDjWhT_hg#<&H8nP- ch9Xvm|G|8<+Kvxz0F7YqboFyt=akR{0H8-FS^xk5 literal 0 HcmV?d00001 diff --git a/xui/gnoll/icon_frame.png b/xui/gnoll/icon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..75b387f588b353ddc46f2727c9723a7294343fd2 GIT binary patch literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6ny3B z;usQf`0eyS(ZdQnu8qRXn*(^K8gOql2=tiI=5<3SVWH5q`Kjzdn^;cWto!uOqID1V z%j4bUb7$$jo4Wq;vl@Td``JHsOuhd+V%=7Uxa^8}KDO3%!SVuMq}ILseO609Bv*35 z#*`ae3s{+I>`ofk9cMmkn0;_J?|i38ilN*A|Mtr;T!=85a)j~XeA5iRet~e~9rmXg zcn&}j)8vl!?$w+z6>E;X3T~6A$_!!FJFdybKUMLr|My0-i(U?EH_Dx7=HtlLVs8&q zsN!^8^WByE#fvLkOH5_V=3J_Xt!ykl{Br%V&$5CyDt4VyKF$jCHG`+CpUXO@geCw= Cxp%$* literal 0 HcmV?d00001 diff --git a/xui/gnoll/menu_left.png b/xui/gnoll/menu_left.png new file mode 100755 index 0000000000000000000000000000000000000000..a49003ce4de8576210401945cff7ace7072aee7b GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{D5&M> z;uvCaIypor<;VL)M-DI?R@*F)BN6X8fl)mnX@NkGltI>k6^zYC85k~cv$n3RbOYJJ N;OXk;vd$@?2>@GnAIAUy literal 0 HcmV?d00001 diff --git a/xui/gnoll/menu_lower.png b/xui/gnoll/menu_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..95cd0df177297072453abe18d7912db7afd5dbcd GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}{5K z;uvCaI=Lh;>Bo5o#)PB=0zFa=tjrPb_AWoeaIF04l%>qmY`<%KVOq*&pv4*Vto5Qn cLIMLr+bP0l+XkKBY-t@ literal 0 HcmV?d00001 diff --git a/xui/gnoll/menu_lower_right.png b/xui/gnoll/menu_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..7aa4bb9b88f8edebad6ec0604154e1da3cbf9293 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C>ZPM z;uvCaI=Lh;>Bsp7<~!Br4?I}ZazJgf!A~C^k)}ZA6$uQd_kI_VDp2FyzT~8ikD<7# z3G=r*i!ZP)k!n~sFNZn7Bo5o#)PB=0zFa&SqD}yHXmhRc&*OZy3Bsp7<~!Br4?I}ZazJgf!A~C^k)}XqH(m+Tgbfl546PpQL9dpq-3rvi N;OXk;vd$@?2>^n1Az}ak literal 0 HcmV?d00001 diff --git a/xui/gnoll/menu_upper.png b/xui/gnoll/menu_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..6b2d146f49ff0ed106675ce9608f534204c7d6bf GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`;E z;uvCaIypor<;Qsk#)O)1znP3W)$a@qcvdj>EKYQ&l-Qub8T5=vjjb(^ne7e(!;d@s V@}Z7G z;uvCaIyuFG*{g}?zoZ9)&J7mp7zv4(DH;X|=WV%S9l8>Ae*Af}=*WS9jqM!b3cqir zh%H-WoXNtY@WiL)lg<$qk&A2(x~#fl7pQbZ_jNWp8Duet@-Q%L?G`#2r}HHjXbXd< LtDnm{r-UW|RLwH& literal 0 HcmV?d00001 diff --git a/xui/gnoll/menu_upper_right.png b/xui/gnoll/menu_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..9019c3554e002b2232375ab1f3e1700cfbe3f501 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{D462u z;uvCaIypor<;QskrXAnsH44r=U!>MsaaL`!!O@6sca;4$cMFvjF5)?`bY>$EOuS-n zz~Diw@MTJDval literal 0 HcmV?d00001 diff --git a/xui/gnoll/overicon_frame.png b/xui/gnoll/overicon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..e11efa5ebfcbd4316830b4610e555cd4ee057e83 GIT binary patch literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6nyFF z;usQf`0ezAyoVKdTp24H*Bs!HT&P{r%6F7wuA=f5?F~+D8TzHHEX{=h)f@9Qxc*BD zy}T)v`19zVOQm;ur@l#E+SnicuZH*MEbf$@jo)7@Dy;6F&e&*D(EawDmU_ruqXQ4( z9%wL#bA0$w)%ftH-6h>;vPBKoCd3?kF12s&SEkcaj9&YvGc&Mx*RPff__@*Q+-c*k zTbF0rPiN9-fFg@N!Sfnf{tKQ=+!T?i;FYhr*>`jWmkxNVhV7eC;q z5_NZ$@Qx_{%{KKVeHONJrd7pSHWnX#x&GK^^Zb)dI}6TUv;%sY!PC{xWt~$(69CBJ BdmsP+ literal 0 HcmV?d00001 diff --git a/xui/gnoll/scroll_bar_lower.png b/xui/gnoll/scroll_bar_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..9a2c0ac32b08c36347b20a0882e79a7625130fcf GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQk(@Ik;M!QGf#mq+@q3D2K*9El0vQ}u=4>??WUy7ocygLJMJ z-!wI1o2K5-?VWsWcK3qpy$8?!U}jpy8&kSpQNXRj?%J+hiziHAD{JRlll>|CiqPEI zH?GW@x8>fOt-I1%LRl+Y0*lzf`UAD4CSLY=cD2^`=A_%o`57N7btJ8M5?gM5tz(q# Ws|-Gp!r~9~4}+(xpUXO@geCxn{cxoK literal 0 HcmV?d00001 diff --git a/xui/gnoll/scroll_bar_middle.png b/xui/gnoll/scroll_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..453539e8707ea177bd2576c5d2ab429b32954346 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}Jwz)sq@Br5SFgsI6YN z>Ticb_k*017Y!B!t}kJkYj1UC^}pXN=W8FHKe)Vj17k~Vo@n#T9YDhw7(8A5T-G@y GGywqPsXNpF literal 0 HcmV?d00001 diff --git a/xui/gnoll/scroll_bar_slider.png b/xui/gnoll/scroll_bar_slider.png new file mode 100755 index 0000000000000000000000000000000000000000..356dd535f3592ff2affe1b66adc8204e7394774c GIT binary patch literal 375 zcmV--0f_#IP)^@R9M5sm)#YDFbqb&xB)A41s#DETmeVW5nMq=a0W)e6*7Vy z0UwYb6=?gV=a{#`fqQ9blK_Tr1v*!t!#~0m=-LY1^K6q47Jfeh>ico&fI|(aPk*0S z;X|+zk^^p$kX&$9LUO_xiJb+m9%%IUdZR#F_0O7SAOx=;(-)VHn+dVNueW}DIq?!= zfx9Z$VxEq)q^Nif`xA$#jz6eqc{~FOhz#hLo#CEQRz4&0r2psiYO$Z zo`)xuWNQ+O+c6TJT$IL0q`;}Nd`lt~PB$h?5)9nbn$0CxI4v-ja0L&~(ji;h^B15R VR)t6;6iWaA002ovPDHLkV1oKskr4m@ literal 0 HcmV?d00001 diff --git a/xui/gnoll/scroll_bar_upper.png b/xui/gnoll/scroll_bar_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..1412b7de16a45445aded0ae40b7cc69f1d38098c GIT binary patch literal 271 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQk(@Ik;M!QGf#mq1|pj`IEA0!l5DJF;o|J%e6%>o-^uAm&9?U} z5&_2-^&NfGanDU3EA)7 znJ1oE9a!+-@Vh!i#hMPAj+Hh3JF?=`7xAUVe@OWDo8@u5hnWXU-L`{|MeHQLmDN{- S@5~2!hQZU-&t;ucLK6V;r)~5A literal 0 HcmV?d00001 diff --git a/xui/gnoll/separator_center.png b/xui/gnoll/separator_center.png new file mode 100755 index 0000000000000000000000000000000000000000..356dd535f3592ff2affe1b66adc8204e7394774c GIT binary patch literal 375 zcmV--0f_#IP)^@R9M5sm)#YDFbqb&xB)A41s#DETmeVW5nMq=a0W)e6*7Vy z0UwYb6=?gV=a{#`fqQ9blK_Tr1v*!t!#~0m=-LY1^K6q47Jfeh>ico&fI|(aPk*0S z;X|+zk^^p$kX&$9LUO_xiJb+m9%%IUdZR#F_0O7SAOx=;(-)VHn+dVNueW}DIq?!= zfx9Z$VxEq)q^Nif`xA$#jz6eqc{~FOhz#hLo#CEQRz4&0r2psiYO$Z zo`)xuWNQ+O+c6TJT$IL0q`;}Nd`lt~PB$h?5)9nbn$0CxI4v-ja0L&~(ji;h^B15R VR)t6;6iWaA002ovPDHLkV1oKskr4m@ literal 0 HcmV?d00001 diff --git a/xui/gnoll/separator_left.png b/xui/gnoll/separator_left.png new file mode 100755 index 0000000000000000000000000000000000000000..6fdd0ebe361fb5991de865101d6730ae1a7ec8e9 GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwZe|H8eIhI(klc_?4 zb3)Fio)a=fJPZ4{r?5!=TP~S=oyVAAx{We3bLvI|t`!Uno0sV6hvsif0ouUe>FVdQ I&MBb@02Ns@c>n+a literal 0 HcmV?d00001 diff --git a/xui/gnoll/separator_middle.png b/xui/gnoll/separator_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..5b4a7b487e5315a9e5eee0b83636f9c0f6329f42 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwZe|HmIJR(U^EGlC3RtArFsN(+sY(xkvTS@6ej^@c+DO9-iuV zjv{xf`&V+zw-IJ$W^V2lVrgG{ERWl+Qq9RsU{bn|aa)DrS&7|gGZ=q7`LCRuv1US( dJL6IYhUY#Gn#*sigad75@O1TaS?83{1OTm;JthDE literal 0 HcmV?d00001 diff --git a/xui/gnoll/separator_right.png b/xui/gnoll/separator_right.png new file mode 100755 index 0000000000000000000000000000000000000000..e58569d9447bd9e1900431dea6a0416dd8cd0295 GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwxrAF+#XwJS`kp7T zMc?@r3c7u^JMZMOr1WR%`p>(YrDZ=TroRyQz}Rz6(qZbJ&>VrJa}1~a9+X8)zrW#$ z>5=>bN$tgnW*=@$^3WGiVf0Ws|C66l{!;XGn}=$R$v;ml5@-4;n&o)wWfkXkb?%~7 o=^Hz@8uN)~?l@)iOIq?M`=xYu&FhXlAU`p9y85}Sb4q9e0E{_W`Tzg` literal 0 HcmV?d00001 diff --git a/xui/gnoll/status_left.png b/xui/gnoll/status_left.png new file mode 100755 index 0000000000000000000000000000000000000000..6eff431156d71b6ccccb77ff05559c7fbe37f83b GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^5EamTas2J%gS>|ocwFlP#7=OE`16Pj&UuMIkHkU_XH^rML z?)%z%-$D41&jB9`7WM}(FA5*#V3@Z(`sR`1b;5zC&dhmNdgcAKTPqk2*z9BdzWK7e z`WemlO6Es4GxN>9@#z%r9JY*KhTDYM(@R6o-F~Taj`6JFowcif1xG)MwxL#j`-(G%8VeL;IM|_7{gH!Q&#p|GF8O}8AJ7jBp00i_>zopr E0Df*}B>(^b literal 0 HcmV?d00001 diff --git a/xui/gnoll/status_lower.png b/xui/gnoll/status_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..c0c69c9cb29c2ce24716dbd5cfd31ecf6e5409b5 GIT binary patch literal 298 zcmV+_0oDGAP)}!Ah1lFn*aa+07*qoM6N<$f@rsQTL1t6 literal 0 HcmV?d00001 diff --git a/xui/gnoll/status_lower_left.png b/xui/gnoll/status_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..8a73b352372ec124978ed4d2608a81e4abc0cddd GIT binary patch literal 546 zcmV+-0^R+IP)bH-ORq#+ZeO1P%aj005xRM?n5P_ID+mTSf*c0gn}stYfLi9$>hv1jb%o zlu{r$KNTntl3?)Ef;|PKILIk*h}q`AU#dX3K=Q6u0U~+;&&I%>g)a^RvS{s&0!0MI zUak`*_Hp*$8n-0eR7k)E&T^)3isp<-6VXx=LL;Iw0wK888W0f%V~R+GU`0V#5)Y-{ zUy7l4zKX!u`$g8;D(}M#iK}W?t3VBKTqC6M0B)tkHMJQscnqgWIVdz+C;6YI3)PP*VwcwOM3swoVkd$DzKnZpWlwh@R zC4>^34}20LLP#=6Cif*kbGt0JJSuAOpcY_k)U;-@Q zk~gbB+@Dh*l|x8ePt%+~u0Tv8o={c+%a|lytAN&em7B6IklDrGDY>^s!!B(}DVV4G0F(8syxZX@B?_lpFU)@*HbH$W)`B0^`(Kw?eQrPh;~cjc+$3f@y> z*OUL>TDxiX!xDsBY;M0_BC#jxl)XyXY&C(uivLBRyN!M?P9RqU;&rWcQ4;kQ7wq+V zk$qsR*G(VXsN9NuprqH?0Us8)YvAp9#GKXq{i2yWaz&N!POvtp9l_ZFpYPL?QHV%X z03M~SCE#Jm=_o|*+81_pR(P0xdQp5e4wv+MK#{Kx(*x{KHPrgf?lymC+k7gzd~pi+ z-~vS>iC0yi)~~bazt@huh6H@F5tSs7QYHqUxFCEqyt)jc!iOE(bKrvlCBf&&q`(27 t(nmZj`>OqIZ~&;NEx!*$YhNvme*ySeSSDK3&z}GQ002ovPDHLkV1in~`l|o{ literal 0 HcmV?d00001 diff --git a/xui/gnoll/status_middle.png b/xui/gnoll/status_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..45b29199dd87d744a91e617904a5be43c6a12531 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6b$in zaSVw#{Pw~|P6h=Y){E<&nAhk+}UUTJkT~W vaR1T29xmr!^T(eKlx1WQa9}_t_Hpwxz1C>m_fVw@Xg-6dtDnm{r-UW|f)+2F literal 0 HcmV?d00001 diff --git a/xui/gnoll/status_right.png b/xui/gnoll/status_right.png new file mode 100755 index 0000000000000000000000000000000000000000..b4b434350979d6606fb19730a17f3da7f93f1a4f GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^5EamTas2IMN8ZB*Jg)JJgd|vlC0YYtD6oVml!$mO6!B3M*yTJ$)hk^0R@oN+t#|+3 z*Z*l*^tLAQA(y%3Ia9|w2~1@Z|Fm^1ST$we`a1dKl&gEPeZ!ubes2gq8~by|m-$D$ zo5D8O=oi0R?!09(%ks}tj=t;9+Hgi;`m6_U=l7k9o~*QP<-0%YIjbgz{mJKyn!NAN u3(>Fa0!|WE$>}l@?8h1l6JQj>2bTQ%ZCkV>iW-1!XYh3Ob6Mw<&;$TYx?*Pl literal 0 HcmV?d00001 diff --git a/xui/gnoll/status_upper.png b/xui/gnoll/status_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..acab93f0639d1e366b62f974915a7c2f66287476 GIT binary patch literal 289 zcmV++0p9+JP)_H9u33f%fqK<9t}oYOqPx&Pc8sYUDE4Y zo~0+3I|jMpaz~i2xYQgRAjEDtgt03(&K-F10CnF10f;dcVXpV&&E9+_FD?LPR)o3U zlM8^V9?WKjs^ZOMTPWq;T+YI^51SVkD(gRi>Sy2qyth|npQn`YDfv&&^?FwFj z5qdvzhBS!@&~T@-6h#V^-^+`?T0zE)h8LV@RStaU0E|8kV4rSDeySY!)dD;afTrUl zMsjQDVn6DvoBP%pxB7eRvy#A>X=?y3x6f6Olu&EnB~5yUY76+MDy+po?StE=1Cxv< z=jaFlY@Gin3yg*rHUM9vJHTeSbqLPCDQPu3f1o?K+E{)Df8hSixZD5`5v;Y*H$-#< zm;^vf#OMW_rhPHstB8oQ0-@AQgeI4}TZ6B^yM5>apG06x99%?{E<{X(Z;%R}6nNXV zfQU1ZIm3(rBAP*cQgz9IV&|!ICK2wc6!_3Npm7|dCkSuu??n|z0q0D?AKU*U(BC17 z@;w0>?rJZ%lxjI}DGTaSskS=Wt<(WkGS!aMhx#{CO(L+6}i%ThTujo;L;#7 zPeenv6c`4V-c9Q5$@6K00zL_8dQIi@rt^#fDrB4cUvQcN;YhZnsufpY4K$YpVSpmy dJjAXk@C^*gTDw_B({um;002ovPDHLkV1lqB=U4y$ literal 0 HcmV?d00001 diff --git a/xui/gnoll/status_upper_right.png b/xui/gnoll/status_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..ecc87d6a654f626448ff9ee43d902b57376878fd GIT binary patch literal 583 zcmV-N0=WH&P)!fDWE0b zcy$mwY$x7X;C=%3CJs>n4nQEjk%gNEVx_L+VoL~_{Y|@T%W;Siz_L5GEQ230h-z!` zaP~QfTEwLrK8=>r_f790#F#r^`*lD!uOO0*&bsqWJHOQcptXiEX8w@p*yWI)RTw|N zQ#O`_fywB#FBmh=+PI%42q~)w3y=U*0KlAAF+&Thbn-V{Pwsc@AWRRO+sTki2Co2s zh(?I;Jl2pI%p8U2dIFIj?(9Uq*SK!jgm*$jl^xeUZ6ArRrt`|BA9A;RbVO9o<-DawH5vMvY>8r$TC@dv!X Vu*6GUx84}8NRnKLN486yy5-Gmp9lwAB j10&0mGk;_m7|Qr(+4D43-rH0OG>O5})z4*}Q$iB}0njOP literal 0 HcmV?d00001 diff --git a/xui/gnoll/tiny_fill_bar_left.png b/xui/gnoll/tiny_fill_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..254499a3118652ea6a841d6a8b117a849f5aa0c5 GIT binary patch literal 400 zcmV;B0dM|^P)P(}8KOz6V#{8@WnzVx7TOp7I`Y|9k zDoEVES*1hOk+~$?6SM+ofm~`|PcYs^#l;ICHUq8kG=je|95<7K{tKH0rG5+O{9X!x zB#c`CHr&d4uL6>f)l~_N;%cD1tU31z5fKoP896K>IJ#)IHi){nZErQ0@`$a4!$(Bp6);r6^!)oi3_jGANAkG&DtIwCM?b-Tc uF?qH+S%I{IFI!IKNGcup-*Wn{_52q+{^0e` z7srr@!*8zz3IbKL1eRzduzE$E({bC-bnFKIccDF!c?}$&tD|~%Xgu%{n~=R(`2b@D zyOG;Qt4Nl5$Ube511f8H-PCVoIBsK1Z;6qB|G6J1nh7ckO@Rx)9jGK7s`7mrDy8s#( zs`?93Bfblufw%J-NLa$NUHsHGRO%xf8^%v`oD|*P8U@HQv1+Wwpq(YCIFzP7eSr# zU1QVF#%njZ)VNcqK3A=?AoXl)+-3*Pj0H!qID!QL8~KU#>ee_9{HnqJejg+bm)81Fx5Ni7 z_}c}*Jhp4q0ADkJy6EUVTI*z+vAE=fcV#h~#PTyAert?5)P5<6OK$j>gfRvXak~%k z4Yo8c&wvj}_)zYL&N#OV)ffD%J z@NNjzNYuUqf)jpU6h0R-+%CVkI8N#?%ec?6SxB4#Un>FQYyMxB1(Z_3 z#S9V41$yCICH4zisE9M+TO|BNt@;V{z`M;{3Nj~Q9w45(&k(B>obdDg1w$ZFH-sqQ zUB@_r?Ukq!poHJI*(QXoD7Pbnb* zUi0-^CScm?T)d~m+Hig5;$-u5%Mj{)@;IsEOMI3D6?||S<(8m?k1k|f64da)Bc*wO z$Q}O*4(gTzK9rgao{6a?DBxFJd8nt7pn&)HKl_r*PCq5A8{Z*Fx7Cfs-Jzy=*dRe# zCAOH9Jc-`JP*+~4Dq$Ou;NG4{(u8eBf@5zbd*MqZxHg880zN0fxvQ0}@VV5vli=Qx z53TU~St2*Za>4%#w7|PgbL&KI9q54v02tintp&bhu`6w-Ss(>a+G%MUB*#!M(L0m? zlyq7m(F=ba=lDw;1E}dVCD98X8;(N?przB01Q&cVH>xL^lnIXQ?Su|S=iIz&gQA^O Z`2*%85623a;;SzuJ#W5%{1D#~xdRe2`O%LT00000NkvXXu0mjfjhJtm literal 0 HcmV?d00001 diff --git a/xui/gnoll/title_bar_right.png b/xui/gnoll/title_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..2b2cec2079faf0ac43dffa5df78d58b3e3616dfa GIT binary patch literal 482 zcmV<80UiE{P)$IB=;hu6NEAFP zpdvZoVHZg8GS`cpGHbsK@UR%TM^>C|K00;NjbmGf_c>l5K|n}(RaGD&G}fL%=9209 zy{4+<(_Eyg$y--DQ_$8x(~ZFLd zD!kfqujbspOY0qM^cjc*M3$>ZwcLe@fpw> zC^);gP0MBF%8q3P5vr$Ey&t#so-B*pcXx(N^4UJ)<*VQPWZe>%mMqs}?F`c3>FVdQ I&MBb@0Q#y=H~;_u literal 0 HcmV?d00001 diff --git a/xui/gnoll/window_left.png b/xui/gnoll/window_left.png new file mode 100755 index 0000000000000000000000000000000000000000..54e60b43214b3ec6c91b6cde8a6b691eb4a8985f GIT binary patch literal 405 zcmV;G0c!q}Fc60Sb})d2wa}9g3sgchAR!tefwK?`wXhbD zaD8AFD1-zqa4>V(r%p)!`DPQoS#DI~M-iY1v*H%09Y91N@@xnc5y4su{aDVnukM*5 zfXZ%7N)hm7fdT*=4~tTchxL?7&AtPGetiB(em7M*U}|U3Ixob!IL+?8Sq9$Xn5)L3jseK=i>R{)_qbQ5c+29eG{X-p|id zJSdO?FbqZ?E(>%8ufPgjp&cP}^w=2~fv(UMx`J28 z2<-u-LLu~KeBqN&MBYb!Oh`ejgs*`Ua9@5Zb(wRMB9Khr8aTwT*e+NFXGt^bCj507k=GGaBG~1Hc`Mnw|mv{|i5lJHYlxU&kF3 zG;Hc`ph*#6)}Zz44c6M{J;uBPJnZe^0RX1I7b=SY7T<5M2=KE4z>a{3FYv|~Sl87F z@oDf*fKm|B^CwwCOsQ@`506bme6XBx*h(!SSSoov> z5)p7u!oj+{KTp?b0=}&PDG@@A;PhhLlF3EjmZ4`CYz-0NO9-Sa!a?7<6rQgV+uvtB zzq$qP&n5PIgX30{V2LI8@WvR>TEn(&V9fJxXW=mmySs`o<=h+#mVC1h1xm5K0R>xn zep=csE#S-&Lh$}xAr>c$w1nc9kO<_{KD;zM9xcM97m&G@!qX&}*ov#$%mE>QEAZRn z>HDz_SnE0AiU3C_50JYz_*ut_phm*ebuxEBW=h>bfU595WN#7F9pFcbpzZ=cN(6N$ z_z@yZBjIt6&;C7D2Q?C&@&T!Dx}_zkk?=HdN#?1Q2x>HZPWr8d25vCA)sN~fv?=PuP)m$B>klFj0oZdx`o+2m!IJDLd*mr@E6`vmNFaZE)t=$iY zr_Z!r`)yr7bp1*@>x15zx}Fl)Spe1f$Py6IiGmN?Jy_8*94#%6`gayUe$T~lH!lWy zPE5Vvai;?k{M!!H{CkSf6aHlxj9EZ05h}rFiTk!2JhOn-BGiD_i=p66+<#G0w6+Mf z;H|YTkmDl6`Y+B3*Ak&7Jda>WgjD}uaG~kNfPGlE+=U?N5XIT`)cFDlJa=Eu?32%5 zDvYFp6^SL(f;YwhBD!y162ZD2oaO5jr>jDpV=AO~KW^6m{!u>!TPR`7f~npz@T!_$FI|J;(;0!rZZVno5x6?kdB zA{OdT5_mcgnFBA47%#%BoKx<8tRNB~1|S`@w2xf)oE#z-f#*L(E|3C{3|b;W34DnN zMXSIWfMn1T5w5^r5g}_C^Z|05F&sQ_>c%S;d4cJsSEg9O3DwO)d}%o zi{Sk}NRV3axpjrN!bs@zS&r~(BZ1FqkyqfQB2ecCuM6;Ki3?J@@meH5RbC5TA_9fN z3K0*#IKorrRR+Q=iUN{QCZ{Gmn-hZn@4zQPHAi|qqExZsfjUoK!RIBZ4rDc z;1g{t_?SC{mO<6Z=cBoT4)7sMh#rz^ R>iGZw002ovPDHLkV1fdl^m70J literal 0 HcmV?d00001 diff --git a/xui/gnoll/window_lower_right.png b/xui/gnoll/window_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..14e3543f34780e2615557fd65af289ffad6c25d6 GIT binary patch literal 1145 zcmV-<1cv*GP)SC5lkvTs^eo)0lz(fQ9&uSgBL=e@B3B6U3dVf zLO`elrS?DHg$F8`0-@8voC0^@s}vBrCWOFOE8vaoE>c(DR#_jnfkt;v%vqsD#4Obyx@xoAb7fSTE)k7_+gl1 zyzhH&33uR&)Bz^Ep68b-vBFcKGYkVn*TYsPgu-VRa0Y)O!CL5CNeF?@It8xa&sKNQ z?We#_mN6Yd;j;trS2%{stU_FhegWx*`J2;PN1KxUS}YJe{(fz<+EN&>41 zzJ!FPB)l3OtAB>Nj6vT);{uU6N?<5>b zVWTCTY)<+_T5Ndlj!;b!a>DPjfTskcl#m<#kOmzWIdRT`mM4)=0{*lPuw3NCIp6YW zWC^9<*G15Akt;k^R52x#ga?2ZU7#z)QAM>IEr(ow7n&kn@9(FC2Y|+BVZ*3EQ6Qz< zpVxaB388JY7)92$26#Y_1oN=sQwgCx#5IDx^0@%t)g9vnK?DhR8>lfPtXZJ6gplrW z3<#z-5#W+B%OVp&@wv;Big~KB>-k0S%GR*t#aZ`|-2Cxg)_R z&-1rPCZPf5!^V{3*R%Kj$4}W43BE;6DhX=@2qB)Fx(=3br^54SN3dJO{CMF7AnGQ2Kf zI^8!IyGT0c7qYA4ZvnY1bW%B{&T=gTPCqlB{rH1(cyWHUXTJ@FI*PzTsAFrYA zFl9aV+ha-uZx4w(3?2a3KY=MDynl*}90jl)1-SF3WeN$IzO3U9me4-_;{}+400000 LNkvXXu0mjfhd>St literal 0 HcmV?d00001 diff --git a/xui/gnoll/window_right.png b/xui/gnoll/window_right.png new file mode 100755 index 0000000000000000000000000000000000000000..587bc2a7c7ea41e4c039da5f455551cb96415b9b GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6uj)| z;usQf`0bRlyoVKdTH^(|Q&`tu5Z%Ni+bC(pt$aZ=LQ%V-wdaCd6o=A7_md07e?LlC zlm11d-h9@Fd7LvicRvuVV2k0ZUZ1_2^#X&ykLWYf%=x8CUNdK2-r4i%p5^tcVIQYf z8rD^RuGTF+Re0jW2fdct#U!L6;#hZr9=6gXHY$O!Op iu(yD?2ku*bVEi^iVv(!Q9%G>Q7(8A5T-G@yGywqL4{-4S literal 0 HcmV?d00001 diff --git a/xui/gnoll/window_upper.png b/xui/gnoll/window_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..8f62ea92a243211a7c3f3a858370ec042e3181e3 GIT binary patch literal 306 zcmV-20nPr2P)FbqZ?E(>%8ufPgjp&cP}^w=2~fv(UMx`J28 z2<-u-LLu~KeBqN&MBYb!Oh`ejgs*`Ua9@5Zb(wRHP)NC`w3LpoF*uT2Ki( z57rWdxh!`_GnshoG4Oxd8;i^!ejPC8Vld(2D;%+jk8RsPYYm)p^S{R>r5p}{uW)?b z0hW+>Ap}S%FXFY=wI7cBMT1byGSq{x(b`8Z<$1~&Uo zDHRNM`k~-w`xQ_s{_76#vjM1Y**rT?#G5pTE?|R5EnI0RhJa(}{db&}5Gdl&dS5I6 zL8KNAPzJ#r!ycyvgdFjgG?=mg-@Rx2V6i<7fywc8lx6MiFhx7l7*)r zP{$~RkRx6xbt&+Y0QgP7zwhV5sEfBD#KdC|tbsrg4=Xp~-70q>Mb(=CrSl=A#LEW+ z$IXE76zTi?=9$-V@r9gP3LvD!n>wHZg1B$V@5BBSjRl`w;E@58KuC$d)Byt_*wt+o zfLsVE@h>6=LCDGitssQN&xTM0AQwVP{7eYN0H_eC;#)wFQa&3jLhOz*&2K)}W=cCfIKk{bVGrg-Z;ru4J6 z7u+xM^SsgF&*g7r=yZ`{FM0gs9mG3}ta1mwMl;gO_{+P9Zw%p}j=#K< z_!$t)xqy2pVvfO97%JZF@(BLw^XSK)^7%jZd2DXJ!r|=++Kp1memiGB-m1vLIa8mf zEDh-#ws0W?aL&!~IP4mF-igu%XA8?i3t*QD%599U9D4fXEb+d4c{wM1X^#)EgpuOC z1%n$DU#^Z2MvD&tm;zyj_!xkp5N3%_0T==SU|yX;0niNZEL?&f_Z4VWTO&75yAmLek{;tyZ+C{gv^043Er$f z?Nc=5!he3$wZUmnYA7KY{@8vFz_FcD3EUr<8%W58FOhK8PKktF9#AQv7(NFe)=sVj z?oUlx>rx5T@F@VP?c_+{1n*~OnG%ZOX%I{S$dPE)^qJ)?l%4IerhE9H>hY7wmBLdS zG~I?X(oI4Ryn3Wht8WD1dj1QBB$%}i{4N4^xq8CMw}2-wN@UI? zBu$G2@K3YAX!v7KpN%=a;Gd_#3GlTNYT);Y&_wuB3AOM)sc<4Z^*}V)itR7C1KbISz%u}hdfyo1BB2Gm zS;5Q-Hd6wRz|-a=w1oFQn(K?vd29efcy z1K#$8?=6AAeGzUD{4MZ3B^)Dw7GjyWT`z!)hCd!VR;^B`X1lvxzbsBO8c#Vn|Gqtx zjKucWY-erIF{Asv#En*=Xgv}@TF*4<36|UYwUOs%u(Uql>K&UD#z$R~IqM3o;6qcO z5W>MHN5IHPXbtc6wm%lQb6}GOCN>H_AYymynWHnC4PPvvwS-ylRRUT`xGH(~hOZXT zLc&?edjxzF0ksmY%3ZzTn+a$sVI+K00WBnqhHoyQM#2pEE&@s<%!2PGAV-3@&4ceM zAXP$29?%QEyMPo4u{ToqNWDmf`@ku^`b4-*iRP`egcDq-~Zgo2ktpn7cmN^Wd9uBHY#MSw4X@_@hz zyT|Wx9+AtHFiikSh)iQPwj5{Hx*FtE0V#q~o-?c|#PU~$7k63xfH!+(c=z{0K!2&C zNMNrF@6QsY68I~_S3KbT`vl~MeK1ifkicFQ{&)%O+RL~c*ek%NCP0C z;us=vIXOfq<;QxJ69*U$Z$4*autz*3NgyOBsiOY99J4Spqk)YG0|P4`d&(z=U-N;w O7(8A5T-G@yGywny#~twi literal 0 HcmV?d00001 diff --git a/xui/goblin/button_lower.png b/xui/goblin/button_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..c2f6871555ad4da8d956b0f235c1a5468880a774 GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&e{ z;us=vIawqm=-2rM_6;0bnuZTTKm5CAyN63+DvRWY=!t1(8t!*hzt3FDz@Tl)y)a7G R+6AbQ!PC{xWt~$(69CYDB1QlJ literal 0 HcmV?d00001 diff --git a/xui/goblin/button_lower_left.png b/xui/goblin/button_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..4159ff6ef79668040e5cc34c78121cbce7c52b74 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCqC$ z;us=vxwa>e^MHYX^L;noBThPJF1uU})}7Njc|+~mfL-4dCVY@9kFXJ|S;-sZW+r*? z^Q%hzH{uDvwy1Wn?qboduEsj`L(ibhyfbS;OXk;vd$@?2>{sV BG0Xq} literal 0 HcmV?d00001 diff --git a/xui/goblin/button_lower_right.png b/xui/goblin/button_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..5347b560b131ddd3ce20ea939be495ee28fba89e GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCp(s z;us=vIawqm=$HPAB}YE|yJyRG@cVa(DJ+r?Dy~Jcv8g$#smdKI;Vst062#*{r~^~ literal 0 HcmV?d00001 diff --git a/xui/goblin/button_middle.png b/xui/goblin/button_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..6e245dc2ab765e7055d50faebd3e321c81c8e909 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@ALX t;us=vIawqm=-2rMb^}8JhQrQ`49O0RDJiih{{dAnc)I$ztaD0e0syO97Nh_G literal 0 HcmV?d00001 diff --git a/xui/goblin/button_right.png b/xui/goblin/button_right.png new file mode 100755 index 0000000000000000000000000000000000000000..37b71cdb10ae06256c2cd2df0a6330f53180d9d0 GIT binary patch literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&Y_ z;us=vIawqm=$HPAB}YE|yJyRG@cVa(DJ+r?Dy~Jcv8k~!B~)lIFmN5=a9Z#|@+D9c NgQu&X%Q~loCIC@)Ac_D0 literal 0 HcmV?d00001 diff --git a/xui/goblin/button_upper.png b/xui/goblin/button_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..eeb3ad4d89ce760200a373d0d82cc0c2f0d5ec1c GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&M> z;us=vIXOfq<;VF3_6>K`tasT>*=_3!24SQ(@pxQligPyP(l O#o+1c=d#Wzp$Py}f*_Ru literal 0 HcmV?d00001 diff --git a/xui/goblin/button_upper_left.png b/xui/goblin/button_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..be65e61807ae481a0107d674498b4cfea177eb99 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCp|x z;us=vx%K=;-UA8(&KLcUFvT6*oRX8aQ#6l7AmVVlf0S&gg0n5cqWB5=$t$N1fSvpIL`^z v)bk%UQFByPWdq_le5qCS@8#^`jTjhgHt{cPp6mP#XfT7PtDnm{r-UW|&@eF1 literal 0 HcmV?d00001 diff --git a/xui/goblin/check_box_off.png b/xui/goblin/check_box_off.png new file mode 100755 index 0000000000000000000000000000000000000000..1ced84160b092de774b334a96eed52825a6c2c85 GIT binary patch literal 427 zcmV;c0aX5pP)Fc3xm?4I`M7Ur5GEzm+*poPsbxoujYg|t8m zv@k9Bx;Jt_4mMf@{(}@tNMMBD!#2ze;Ak2!X~5(eLp<>A{r~{<-yg8ZjU_C+eeafQ zRa!#4aIb`T;KNT307!j|gm~axGoSY(FCi?v)#5%aAzrvwLe7ADB*X)^xPV!Si|5TP zE=S(iHOm)bX6Wt@Z2d8Xg%4KFKsst?LcH)C$VkW;aF2wX1!pBL8Zc?o7V!MxG{6x! zvoSCD=k~V*+O$yBVisOa1CVBwpwpk_}1JbX789g)a`QZ4*YINpLuS&`G zBp7&gQu<0F?EwZ(rR8ghJT0$<(}hVcQS5mV+1y-OVbOo=Fj*zav3LPP=kQKB7 zBaj~rMQ~8ir`*MNxeMgt_iW3S1tgl*7`4Wj=|eK`a=8Kky6-R8!1X08y!|Zmvnnki zS$I}LGVuPV0{~3#7zxS1OY{4^yYmvl!dqSZPD@A@o|TYSz%vq(f!i>HS&1q$avSE4 ze^;7$hnN}4<%+!%Q&@O!fZd*>{OF)HHxrVAyER}XBn9_DKuSm&?n#71r8P!v+6CPI zdFtR_xQj@;l~7<-cys$(0&QBT>S7kQrt!=Y>@DAVnQee9f{>OV;hWnqEaA3c6ux^9 zg(RK_5d+`N1rZ4VH2g3bossZKDGEQ8j*leRk%ulMXC*YYTwE=;_{A_ju+RB5)BVBqQEbV}oP@9E++)m~AaKLB&gf53Q>{el1h002ov JPDHLkV1mmAvKjyY literal 0 HcmV?d00001 diff --git a/xui/goblin/cursor.png b/xui/goblin/cursor.png new file mode 100755 index 0000000000000000000000000000000000000000..2efa14fd8baa0aa2e1351a9a16df69f0533f8962 GIT binary patch literal 355 zcmV-p0i6DcP)TB_0}RgNFmHrV_Qu{9W+Y!(2(ug{mjP6XNCn?Ozmncs!{iV#}#`Ul8nchhM8 zjL4`<(kN2vjcD`x@$Ay&hJfYS{I1lOI(XQ(N}_U@i()c$cB*nYP{ApkqBR)M5_3J8 zx+Y-ON-50(Mx&VOgN9My=)9-uzxfnZqM*QV&cQhc@4bSZRs&{M>l~m_i=NB%s3^65 zMuOEEh*RI@YY(s5j4G-iLQM7Iw3$ZLb-x0%z*M~+Xfjb301y#E2;he+^g%lK1|ZA~ zB2ogdRTcHv!4ZMf!nQyQn-Wr#OW19}Eu;mt;1Y5V zIef%FfDm9iXT9vp8f!)ppo!dp(9pmWb~GBHlRU3WIAIY0O>^KdkbE6g${8Blf-gn5 zE|vZ*3Gl(Afv2Pllmz_!3wF2rmuw$W67Vgf9x4Y33A!fuQUt~7-I35g_~oD^;6nh> zl-a1zgx}-)l9LHq0zMXDG-Zyelq_>ZaWg?nz|#m_3ge@}EO2I|6aqScmk&84C<%Bt zh|vh0pOKt$P-h1(B|&`xcnJyWQ^4nvpgswF4hibhz;j9HO7!#Y!ZT}9005wW)IA1^ zbc2$9zJH|s-}qyB;BUj!?9|i~^!zp@v0?ld>AP8pUh1{bE;FVlZ*3$oc!yP&YFr2q ztbIip5uxvUv7=L@#^u`9kho-vDMFL8L~no3u(qn@=xR+{OiF)O|EX(Nlf*b>fk5E= zBcdYdKh^7OZ3N=^W-5peM=KW5SwjE>=YOJruJ}paUuk2zqTp(&+Q`MBH$w6BH$w6 zBH$w6BA}@)dVzu1nqkvsh={iD+>d=DDD^FgfLK?RGB2{vf za)!kGi_J0U(1To=JSJTS)u2cgL?!pFcG(CsAUPEaOV@9H1SEHyT1|-}w^CQQXuB+YzBfiB3KGb}%+;Ov`S?aWlT4VI=BydK3)K*%Zl?3jb zlM2<=*+|G4@=~!4<}4)SPPj#Hf@dH>GTxUahy*6GlkNZ&$K9l}jmh5&1W2f=C&c=B z>0qa3I%AH3V=WL=ktF6r(>hf-FK-w00000NkvXXu0mjfQCOCT literal 0 HcmV?d00001 diff --git a/xui/goblin/fill_bar_base.png b/xui/goblin/fill_bar_base.png new file mode 100755 index 0000000000000000000000000000000000000000..31afc91e16384477651231324034b6f277f09be7 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQk(@Ik;M!QGf#mqmQ)aMlT0lhYklyus-;*c*Tk z<*}~GIV6BoNOG(wXid%`0Z>9}g4X05(gP?VKFnX|>w8VkApvk_(Fb18nw&!d;Dk62 zfM>%BqN0{VLFii5Uy0*t#GB7y{J-9Vzd69uxTf><9rHCg=~z2TI7he?_ND_N5kJAL z2m;XO#Bp{KHx&vJgV2bV3Zn8P5W0LoE<8qNPQE#ayMd7d8vgtR@A>cC1Hue|3kb%T z@dJopt(`$gjU^YX0kIZ>`?8>&Ii(yQp!hC z&B;Bfqt;`o$)KiM3lOzBPfmMf4po^%07@p)5(FhEUskCQ&P+==A^`c>k&536f`U*J zQagbq@c;llHxPhvJ=IK+HOpzKm>CGJeEKj>-E?|OgxrsPYjTPJV$_@px}qm|Cccyc7~ZSsIwlk&nPK(@{Izf13_0NCqg+7F1cfNED?6{T@##@G{A zRF6LUdYSeHQo_#=FZqsiMrz&@?+K<`W34twS}p^P2e>awmO;^`sPxv=k%I%USOQz` z4Zd|5Fn+GiJ*|*$mcq1Ynaly_!G8O#6Jx$bdm9uIr+(6!@eNkQYF*dQ$alYf5~qII*P&5 L)z4*}Q$iB}j#*Bu literal 0 HcmV?d00001 diff --git a/xui/goblin/fill_bar_right.png b/xui/goblin/fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..539e94098c5ced7d53319a86b4eb29f97c1b3c09 GIT binary patch literal 334 zcmV-U0kQsxP)X&eSlSyX zJ_izgPJ%aNi9V4a5#x5zyg(9<+tU}9NPD_lk%Om%_GQY3APiMr|L2Tl1p1u734a; z<<%jl-`!7FFo(Q_df?UnA}jpVfruP_Xx;N+hFATIJn*Um#{&m|cDukUbOpb4;8@_* g4y^Dy0s;S0ZwAZ2Xkx_;F#rGn07*qoM6N<$f*LW9)Bpeg literal 0 HcmV?d00001 diff --git a/xui/goblin/frame_left.png b/xui/goblin/frame_left.png new file mode 100755 index 0000000000000000000000000000000000000000..7f7e35d972541b161f33ea60ba7f33b6a78349be GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&D; z;us=vIXOfq<;QxJ69*U$Z$4*aaHsnGffEd@K0GW3J_Il@yf9%ESa9cdFi<^%r>mdK II;Vst0H+NfO#lD@ literal 0 HcmV?d00001 diff --git a/xui/goblin/frame_lower.png b/xui/goblin/frame_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..ed848663be86787d9cfaaddd28ac0540e07f6a58 GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@AOY z;us=vIXPj0WkQHh%8!13M(lmi1FarSt*KZ!5#(Lu$K(iP;UHx3vIVCg!0KH!+00000 literal 0 HcmV?d00001 diff --git a/xui/goblin/frame_lower_right.png b/xui/goblin/frame_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..d6366c726b9ea23a8f1a749b0102095af77fdd56 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`>F z;us=vIXT6F$*YOy|5O%9iG+%4k!);gY)lOcn8Z{a+x}OGE|FZ!b*H+28AB|?VHPJY d3C^92491_h*E;{-y#Z(lgQu&X%Q~loCIF;9BDeqm literal 0 HcmV?d00001 diff --git a/xui/goblin/frame_right.png b/xui/goblin/frame_right.png new file mode 100755 index 0000000000000000000000000000000000000000..41d3913c02d534268c5d1bc54e195b3060851ee7 GIT binary patch literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&7+ z;us=vIXT6F$*YOy|5O%9iG+%4k!);gY)lCi8Vn3Prp!(a*JjQDs%7wW^>bP0l+XkK Dcz75w literal 0 HcmV?d00001 diff --git a/xui/goblin/frame_upper.png b/xui/goblin/frame_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..180bf962ecb8f9821080062f0ef02ccadac6b7df GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@Aac z;us=vIXOfq<;VF3_6AmVVlf0S&gg0n5cqWB5=x_!f=uqi=n4reS d)Ubew;rL@7pXfiQx`1Xdc)I$ztaD0e0sz(!DB1u3 literal 0 HcmV?d00001 diff --git a/xui/goblin/icon_frame.png b/xui/goblin/icon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..cce0dcd863c4accd464c7c3afa1aa3979b581031 GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6kOx! z;usQf`0ezKyoU{VSmrmX?Tj?(ZhNFNt97-8ufUDI*r3cGvW$#29Xb_kI=MbBH#V9j ze7(oI#Jv2w{Dg0smu8>0yjne7g|X%4@m%iV7Z zB=hXtJO}gLrK#SM9 z;us=vIXNUK=-2usOO7xc-kf$esp9;B0}3ma9Qp9?o-Lai8&g7s1_J}rLynaH9#^t~ Px)?lN{an^LB{Ts5$G9VB literal 0 HcmV?d00001 diff --git a/xui/goblin/menu_lower.png b/xui/goblin/menu_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..6bbb18f951025c6dd893c1e33c7dbb7e9f807e33 GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&G< z;us=vIawqm=-2rM_6;0bnuZTTKm5CA`-h7~@&og`U)Re@^5Z%Dr9GxOo Q2-L^m>FVdQ&MBb@0H~57#Q*>R literal 0 HcmV?d00001 diff --git a/xui/goblin/menu_lower_left.png b/xui/goblin/menu_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..97965e4aefa9d9d54c2f165bf90b1e4c2d727f6c GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D468w z;us=vxwbEm_keyZ5ObVUZ znWysah4-OJUK3g@)6X83yZw&uPQKCST>^p~9bWsZUQhC>m^J&^yW`U}S27-`P~W!E alJV#vV+-*{tN%b789ZJ6T-G@yGywqqT0PkS literal 0 HcmV?d00001 diff --git a/xui/goblin/menu_middle.png b/xui/goblin/menu_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..6e245dc2ab765e7055d50faebd3e321c81c8e909 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@ALX t;us=vIawqm=-2rMb^}8JhQrQ`49O0RDJiih{{dAnc)I$ztaD0e0syO97Nh_G literal 0 HcmV?d00001 diff --git a/xui/goblin/menu_right.png b/xui/goblin/menu_right.png new file mode 100755 index 0000000000000000000000000000000000000000..96f24b49adb245fb6db613d35610f2ae1470aef3 GIT binary patch literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&Y_ z;us=vIawqm=$HPAB}YE|yJySh$i~K|s;X)+&oo<%S(us8z($0D!CaHQG`T8!BTy5A Mr>mdKI;Vst0H^93WB>pF literal 0 HcmV?d00001 diff --git a/xui/goblin/menu_upper.png b/xui/goblin/menu_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..075d136e26768badd4abaf3e4a057996d2b64029 GIT binary patch literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&Y_ z;us=vIXNUK=-2rM_6ZYP z;us=vIkzuR@PGk_^W}RySDdyiU=8f(ZuNSx@5YO;x*aicioEj`cdp7)KYX{m;fc{^ z7C}LeyOXDUxjpGZcF8Q!9Y)*Y&INs{OiYX3>6kP@zhIW;L$*`B8e6hAe6<2v!QkoY K=d#Wzp$Py_J~^iV literal 0 HcmV?d00001 diff --git a/xui/goblin/menu_upper_right.png b/xui/goblin/menu_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..17a673d0b087e46ca3466c36b7f4afa3efc4216f GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D46Bx z;us=vIkzuR@UQ`o^ZaU60j@(rItPV#jtS{33gEcuzy0&Bm+tAmBbQIuqPa=7w9oQ6 z`-wC1AGYuwi0Zy)%`oZ2nOtkW+j|x+XRcv9zj%r4+9^3p??^PCd6FZzC5Rt8U3KbLh*2~7ZDt3jOr literal 0 HcmV?d00001 diff --git a/xui/goblin/overicon_frame.png b/xui/goblin/overicon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..f0906780f56308caeab5abe5d5c7e67e39868123 GIT binary patch literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6kO-& z;usQf`0e!Fg3g8;gi-h^Y?pKU(@nrdh$+LY0aIUjHf?XWvXNt7{1;MzkeY8?g5SaGN<^B z?+L6m-MPEVjNL-!k8`~rlZpcZP5GJsU)sSXW=SHDlrT7V=|WWWGuG|e7T$;XVrPdZ mY&MzmH8b^%o6NRXzl5Kz2@BrzNyQ%Mat2RVKbLh*2~7ZE0$dgV literal 0 HcmV?d00001 diff --git a/xui/goblin/scroll_bar_lower.png b/xui/goblin/scroll_bar_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..0ea255d4ee2a7b488893840a816b01c383923dd4 GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQk(@Ik;M!QGf#mq#$fq+YVfK&l@aCf$6;JVc41+AF}Ra=+6WoJCv(=vdQ1soi07S_HS?z1rB~-p zIS2_}eDfra$w6rOTJO^5H;$PJ9yIY?FI%#=X^Yg4PX4cl*)k^@n@-Cq@3>kga_v~2 zN&LdHoEP?o%$0Ng9-7C&zhKXyMgEK5I$rw2)BU^Lmg(FM_HMZ|y2?BU_O!2^*2bH# cr}ZcItmdKI;Vst00BI3RsaA1 literal 0 HcmV?d00001 diff --git a/xui/goblin/scroll_bar_middle.png b/xui/goblin/scroll_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..c13f056147bdd31bf9dc8be65b25aea3a30f1ec5 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwYh=ZbpX+vWpYj%dV=HKJ1e*Lw5 z#N*-ZeRx%USUPJV+nbx4+l}<^>@M$5VlG&AmV+1y-OVbOo=Fj*zav3LPP=kQKB7 zBaj~rMQ~8ir`*MNxeMgt_iW3S1tgl*7`4Wj=|eK`a=8Kky6-R8!1X08y!|Zmvnnki zS$I}LGVuPV0{~3#7zxS1OY{4^yYmvl!dqSZPD@A@o|TYSz%vq(f!i>HS&1q$avSE4 ze^;7$hnN}4<%+!%Q&@O!fZd*>{OF)HHxrVAyER}XBn9_DKuSm&?n#71r8P!v+6CPI zdFtR_xQj@;l~7<-cys$(0&QBT>S7kQrt!=Y>@DAVnQee9f{>OV;hWnqEaA3c6ux^9 zg(RK_5d+`N1rZ4VH2g3bossZKDGEQ8j*leRk%ulMXC*YYTwE=;_{A_ju+RB5)BVBqQEbV}oP@9E++)m~AaKLB&gf53Q>{el1h002ov JPDHLkV1mmAvKjyY literal 0 HcmV?d00001 diff --git a/xui/goblin/scroll_bar_upper.png b/xui/goblin/scroll_bar_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..5b90ade7ed420075a8b9dd5ba5e919c46b8f1ab0 GIT binary patch literal 277 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQk(@Ik;M!QGf#mqsdqY!t;xxXaIx~-I8!&y()V>vzp*{Cq@w874UNY)RWh&fq z4wF{j?@Q@4YnaYfEa328H)|6KE+V?)WQsVS3oxBBmWq@(C99mqYMrS$rp$TucZiah_0*SF;N z7qIVF|L}G1ezgfDCf)2Tkq!?|>Rc<9mF(MZ)NO6HT~OfAtoxhR%E>TuF>i1alGpvn YEF@XKi$9&|AJ9t-p00i_>zopr0Er1`uK)l5 literal 0 HcmV?d00001 diff --git a/xui/goblin/separator_center.png b/xui/goblin/separator_center.png new file mode 100755 index 0000000000000000000000000000000000000000..b6c208a9378cb6718352ee11443808f6f34ff031 GIT binary patch literal 415 zcmV;Q0bu@#P)mV+1y-OVbOo=Fj*zav3LPP=kQKB7 zBaj~rMQ~8ir`*MNxeMgt_iW3S1tgl*7`4Wj=|eK`a=8Kky6-R8!1X08y!|Zmvnnki zS$I}LGVuPV0{~3#7zxS1OY{4^yYmvl!dqSZPD@A@o|TYSz%vq(f!i>HS&1q$avSE4 ze^;7$hnN}4<%+!%Q&@O!fZd*>{OF)HHxrVAyER}XBn9_DKuSm&?n#71r8P!v+6CPI zdFtR_xQj@;l~7<-cys$(0&QBT>S7kQrt!=Y>@DAVnQee9f{>OV;hWnqEaA3c6ux^9 zg(RK_5d+`N1rZ4VH2g3bossZKDGEQ8j*leRk%ulMXC*YYTwE=;_{A_ju+RB5)BVBqQEbV}oP@9E++)m~AaKLB&gf53Q>{el1h002ov JPDHLkV1mmAvKjyY literal 0 HcmV?d00001 diff --git a/xui/goblin/separator_left.png b/xui/goblin/separator_left.png new file mode 100755 index 0000000000000000000000000000000000000000..7c9c6cfc99e7e2e6d712a60569c947abf0d9fd91 GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}Jw9CUHIB o{A9)a>sZe$#)TW>f0#N*CvmdKI;Vst0Mvv>AOHXW literal 0 HcmV?d00001 diff --git a/xui/goblin/separator_middle.png b/xui/goblin/separator_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..64030390b154c891c0b1e3df0ec807749296498b GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwZe|HmIJRVI;ocPPP9`MxQBdj7Ql5-mrG@O0b47F#O!h?s3L? RN)k{bgQu&X%Q~loCICqfBCP-b literal 0 HcmV?d00001 diff --git a/xui/goblin/separator_right.png b/xui/goblin/separator_right.png new file mode 100755 index 0000000000000000000000000000000000000000..45f639f6530111450cf7e2aa5bba30c3fd321023 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}Jw;ptZE8>Kyg}Cb>Hr>mdKI;Vst E03$0;+5i9m literal 0 HcmV?d00001 diff --git a/xui/goblin/status_left.png b/xui/goblin/status_left.png new file mode 100755 index 0000000000000000000000000000000000000000..8b453554e31eaffaf7b9e92487519ab5bbf88ca9 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6x{0R z;usQf`0bR7yoU^UT>86MH#Mc7)QM~qopEq;MeCXZ?Ua^J&VeEmGLo;zzmflaeBWiy zI&sekRYrylU+b=MO}Qv06#hYHmhw~nrIA~j+&xyYR6My{dq62n`GAf~fXTv3 zXXH3mE3LbAh9Tgqm2qa;imJfsglbPkWdq}-EM2Bsv_I(mYkMVgqv+pGrfgR4#4u{Emu-ZhFIeJvNEJwf{e%glR%fg&BYoInpSc)I$ztaD0e F0suW@WmEtF literal 0 HcmV?d00001 diff --git a/xui/goblin/status_lower_left.png b/xui/goblin/status_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..28778cbf8cd1570b9d89fa43043b2d6525493694 GIT binary patch literal 414 zcmV;P0b%}$P)6SQrafSPNKK3#$PwV*v}XfP~qH z8BT9NVYoCe<(vZfn&eL-NZ~~a0D$n^uB`*i?;n^MM`LENd*bT6R|G`_|G8tkUNFf# zGZfKjJq;iQF%=*NF&*I66vQB8$!2B-eTYx*TpNTak>Nqpt#bgY3P{z3Jn9^44G=17pojAsr>6+u zMiaX)*rX#w#yWugeqZcNu94{BaqzE8K#}-gy&6~CT)_)1dv21s?_UL6iEOqbG^<_7{9*JKf8LUD*AjJ+P7Qq zPmT6YI6!+R99E9t;{xu419V=vsv;umdryOaRD1#+KiL<7vESaz1`qb^0kpinO#x<4 z%R9_tvPZ2hK&t}w)Gb~h48!pHp$Iu=M$yGX_cgR8TRn%?fwLk)uc0M`f-IBRJ-6g5@Wc0jrJsA?rc!*=&pq&vQtW|; w+yW0gQb2RnzVr5T5B$`7Afg3_Mj%SWFH@f9Zkl~n0000007*qoM6N<$g0%IiOaK4? literal 0 HcmV?d00001 diff --git a/xui/goblin/status_middle.png b/xui/goblin/status_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..a41240361c7ab78b60a17f11f5e659fd6c601a49 GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6x8>0 zaSVw#{Pvt7BLf2qgMmqa3*0;?c|o6mWpC+KF+BnuAb0P%DF{tDnm{ Hr-UW|M(895 literal 0 HcmV?d00001 diff --git a/xui/goblin/status_right.png b/xui/goblin/status_right.png new file mode 100755 index 0000000000000000000000000000000000000000..64569267c9518a4298be3c90731d8ecd5ed1a0ef GIT binary patch literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6kO@) z;usQf`0bR_yiA4y&g@nm++%chA;jmk)jF5r%4l9|?`8r7mEUARgAr{<>P?d6^a z4##;ltbI})o9S^oI`;eTO*0-oV>?ha(M0e2{Qv9sR)(nb-rc`=cYYS*t0#dwf43*z z-CeD7AcL7f=lPu;&uyRMrB(!oU+(xhg{{xY#bjw?ZO4jbrUt84^3LHhxaFYfDkH#t hgt5>8iE0e4Vw$wb)0bQMxjE3$44$rjF6*2UngG0~T7dun literal 0 HcmV?d00001 diff --git a/xui/goblin/status_upper.png b/xui/goblin/status_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..653ca08d20d0d8d7b2f67712ac511d20fe3479bb GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6x`tH z;usQf_-)uh!NUd|lV$Y}aIHDOb>@+!(Twy&*8T}Lm%iMJyDa}y@XJHRa|KMdwR~;} zbX;RyxPrrNb7e7W5z9)49sqTBrpq)IvmIp%!AH7On*(v>zSP zOk2WZ3Ei1Y@)0#u(E@I6r2H5Nh5OC1ti-99KnmdC(@P!J>bnrI0Bv& zFbe)tz)1L45}pMonM}kZ#OTNbvdA& zY=po$w>2K`Jr-ehZ__iQW4leY-O~ls!n3oWCM*IXvPo|4&+RkkN~=bMv(z=BmU&)! zYgXL{QuACyu-<%jeXydukR;k@ZNhz;73p6EHSj?GM?i$1(g$kb!$a^19~y#RZ~%A$ X{GGNg@%|_H00000NkvXXu0mjfHh-E+ literal 0 HcmV?d00001 diff --git a/xui/goblin/status_upper_right.png b/xui/goblin/status_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..ee509868847db4fb8d278f5387141bcbe74de7fe GIT binary patch literal 476 zcmV<20VDp2P)xS=B$G4$*=emb2Pf#{C$Y;v)9OBlxXP0z{2;?~oK zvG*VN=?-xj0An9SRSQb}P7pe`w_~hHo`X#9&Q@Y5Zm`le6GG@*uMdNBZWlmA5WW?# z0_Pk=${?!x`w&?LVU9jba`*R9gb?7ITi{g{0v2b&G*5j7h9pE}SyMBZO#mW-5JC|! zRaGhQ6SENJ)Y*3j=kjqmkc9Uhs#-jv=Bxk-Um+-QsnU9`au6mr-JA=RNJ(jn7uOMl z(XUVZWiW1q>{)w?en45@hNH_W=O?OXU_Je*{Jnmn>M|m^5t)``xy!9s0cVL2Wh*k? zHw#s_4m^uYYob0s03zjESEAQHR#!mqP&w2kPiv9}96_8grF`pZ6ElXxMlR$lCw$k4 z8E_wdw<3$5C;?az#EyZg@e^537)e+WTovQpJzWPero>l4ytLp7h)oOr8{!8g*7DE~ Shw;e(0000zl~AficYoqn&D zP_6J*3Dp93R|^2ppJpWi&&Lbo;ARNdc6^jD#K#Hb;F^-(`@Dqi_a#oPZ~*XsfF|JT zM$pFq?>)5ExPCL}?CT>?0$=@qBN7Cb3zWdwFW^0it-?IDJo)$=!Vdub`FT3VpOB8> zJxFQ__jk2$#{hqs@bODDVr0y)yr#?yV+G?MK}hXM?JPNh-0b0U;a!-lPIE sV2W+E1zsg^FA>{o?cua(9dSJW2mV{WtY1usWB>pF07*qoM6N<$f)Do7g#Z8m literal 0 HcmV?d00001 diff --git a/xui/goblin/tiny_fill_bar_middle.png b/xui/goblin/tiny_fill_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..c906642771c14500116eee224b0b50b67601b5ad GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg`npr$CtT@x&!cK*1HB zE{-7)hu=;+$jhwA!(uMOdx1%J2kUhw*>H)iJ6OF=*y=et?mDe~&F<0P4-qZy$D$-T z{_d9B`rstX3Ev&EC(L#*blNh1;rqb2O5+UAs^^ue{`S|S7#a4KZ@HEy|M8Q#;7xDM z&y!Xq^?Z%D`RnUa_Fn1!AI<|!5eyOnFSC-)zA0N!_f|daqiUDrQFVsZKO~Rp2Zu5; ryifSWBj9f@HYvg*Ns+Vlg%yLxRnKkL%dhwX-OS+W>gTe~DWM4fkab;U literal 0 HcmV?d00001 diff --git a/xui/goblin/tiny_fill_bar_right.png b/xui/goblin/tiny_fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..b21e6bc708ebc059a808f9398acb4dffc4145721 GIT binary patch literal 341 zcmV-b0jmCqP)#rRoh{(l7yW63M2w;XH#;k@l|^u zC%|HFp!gI>^eJ(NEYU|2Bw|=MO%0N`Z%cFvpS1YiBpCJgi>Z++;w*0_oMNaxI00000NkvXXu0mjfPr{0G literal 0 HcmV?d00001 diff --git a/xui/goblin/title_bar_left.png b/xui/goblin/title_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..a8eb724be87178fa69857caa70d7eb05afdfe5a5 GIT binary patch literal 895 zcmV-_1AzRAP)iZ>cyneV@!ZSUJOQC9}3_Ye6EOE`=J0*!AnKd+7AW51<#47wI2#V8hlDbt^H5{so>qV4>%

HlO{D6S25VMJ& zzgeKRr*@ZG ze~?UGnL$d$pW*-FR{>8dTyK~6&u2c64(S%_cnWwA|H&z^ynljoPAp#XrfS6Z^548B zmtTyUfPcLN|=igfvArj>s+Qhe!- zuBCr9Qhdp_wzYqCw)oW9K?0$Ne|74cZ?Ly-?O&ZK{x6;#R8R5#K!vTt(jari=lX9l z0!r%vk{~6=^zQY5QW32nU>lkm@oYVyl?dtbmJ2~5o+^lh_RUs-vmoS%uc`;EUmu{g zCJUOaAxLU~HAxwR7gdD9Dr{I8$|;PbDmTyD8RQLyfs3xm7$4G{fdarl^n`!~o(rKw zJPY91VQUE7kyd(F$oZghMszb&dpUZ{34Y#Vw=P92c;8p8eHMT)^IK~p05wf2B2~$$wMVDG<2y9Fuf$-Nqta!F90@mkI7e@8?qiRR zfQQ4~C}@=fauXX@;A~-!0tg{+gnL2A3BJ}I1>hl^0l-hG@D4J!&suvFz!AiMXurth VNp-$JJz@X=002ovPDHLkV1nG4n5h5& literal 0 HcmV?d00001 diff --git a/xui/goblin/title_bar_middle.png b/xui/goblin/title_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..31f331e983f2e10bfeb061ddf38cc6c08d3e9e39 GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^(m<@i!3HGxts29C6lZ})WHAH7%u^uD_;}(HC7@ut zr;B4q#NoHs5Aq&R;9w2NiCLiiM|2m{<`RwcM6s|J9B}SlEq&N|ipbe*W zJp<1>Ut08QYJ0Ad{oP2tHfLc&1^#Y5gUxo~S1V`CEM;iea?L4W$CtZ*P5t(#D+m0L z2;KVp%-!eDa+YY=Rj=z1RCeo;Fii3`7n^DS=+L>zbDtaCV1Dvb!|Yzg!fv3G7(8A5 KT-G@yGywpB`BCHm literal 0 HcmV?d00001 diff --git a/xui/goblin/title_bar_right.png b/xui/goblin/title_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..611c36495748289432a06577aba0ab1a897a024c GIT binary patch literal 476 zcmV<20VDp2P)oh@i66Q#;!1IxmR#D1xqGVDcMszwjC}q8lJ0#ZVa*0TBT+7egh#mRnP=rZkG{I+Y%BB1Qb; z4pXc;GGi3A@mMoX*iqzIgP5*rIz#}xoHDLXw3hzKQ&WgvMI&`9JNJBmU4#CtiQg1r z-1G7I%cfDcOD`Nvk>}z!K0+?b_cZ5C@jK$*nj2+Fo=~4gprtN-1daw2&)7f1HtbBA Skk?EA0000Xl4lqT$cqSmTFI~}YMh5c?Hl44I&a*QY z=*ayLkSIN{g4s>h;8jB)dyiGZ6~@JU5~U1b>=$;r_7ogoi0IiJZ@^LIU6MO*bC1t` bWkv?APa+%(l%vgnwla9S`njxgN@xNAeJwlG literal 0 HcmV?d00001 diff --git a/xui/goblin/window_left.png b/xui/goblin/window_left.png new file mode 100755 index 0000000000000000000000000000000000000000..3d8907e8d9e98d00b0b0f7bcd1249f13385f698b GIT binary patch literal 253 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 literal 0 HcmV?d00001 diff --git a/xui/goblin/window_right.png b/xui/goblin/window_right.png new file mode 100755 index 0000000000000000000000000000000000000000..590f944520dc1ef90c996e89962c5b7fa26c27fa GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6kOuz z;usQf`0bR7yoU^UT;w}gHyv7gfNP%7=9JcT4@8Za{!9o^6y;K44c#Vk(|+1{|K~DO zc4#ma9??}D299M1t!&)xNpWgk6TK=Ji~6UQ+Z@vBhv%r zBR8_wIiH9$5$pS3)ELN*!-}u zqv9U(=AQ5C@=xTsuxdStEZCrWg4Kb|gH_zYk!`lO h@t@B{BZSs)%}I&M3=0)|a17{F22WQ%mvv4FO#n8ISTO(q literal 0 HcmV?d00001 diff --git a/xui/goblin/window_upper_left.png b/xui/goblin/window_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..52275dabc3a0c4504b397d086e1f997983c4a498 GIT binary patch literal 1117 zcmV-j1fu(iP)t_PyTRX&w85A_PZ!GB?% zX8=bac}rC>AXiMZ2B04BM0AT5sJn=}ACi^^fIrj%J`H?V8f-GVgwI=R|8sdJ1%^JK z`=35Y?*;44Tt`3;>bHQBb|Ckk=VS05v(3cOZy zNO|5J1HzjmSC{Jcik~pgAEiyY2zaRz3gETYYYZTwjrott^M_;srx4U1h*GrA`Mmoh zu{y>&N-9AA-qQ2lh7(W=J{#@vNn+D@&1PGM3?&%XO;)~W{Md>iRIrGdeXsYqd<>W$BZ6QD zct4CWVkER=if#gWgiTxo9Yuoq5|YCb;A1srjDfSaBko6oKbi!;=dt&?b9~-fyT0Dt z67H>e-b-4oH5g-dNysTa2@*=dt($;ck>hW=Bx!TM=^;Tm0*wP*pr*(vfp--|aY#^( zzt6~X58i`G613CSiYvTODCMpf69@pw6d8i|uTmj2L=NX9EktFii@HE55@JGA zbpm(gOD%nows>gvzQ*3v;~95I1=ZLcq|IKGfRw6B36&fPsn6H<1HpF_kP zlZk%5*S)_}E5Yo_NBOuURbvvg)<8r+M4PtxUgPx=J;AVbZQZ{9E|K5^BlnEJDHag6 zu2Y*MwatpwI$@MmOkA_yOX)2go7fWQVRwO!a)XHlUgdjmu3<%2OZbcST(vh^4p;Be z=CVL$5(~Vq`i2~l;eh8@fEt|VyDWgSKi^^jXM->I0}^>&$^xzcKI;NR1O}-}QMG1) z7VunxYU9ES0a_7Q0`}pAD}ZmASG6%BIaEl`5* zBf%joAR%y)^)i!jGGk-({E(hx<${PC5nZ4#(7*;K9`mv+u&!$r1d9M@&Sf}x07n25 z5y7%7fQVb|Wb)@SK0MGF03d)+W5SsLh}k^v1`0r^4d+q4AZzG-K48Qo&Lb?#qP~7z z*SCQ%_wFSC00e?{UDY7mnFk1TIOT@{5GGAQKtw>qj{yPAv(p>O05rEy5^)0P{<{@~ z$Oi#<`dL1JJUpD{ZSh+#2pUJM5pmNYahB*pL_kEEYgt_~lmVJWNHu8b zIWj?{V#~Q4)-#}>b2~XQmlnZ?EdYSd$)j4RNBL{+WZZ{ecZ<^pc2(Tc( zkoBrzfal}9R1Xvx!bArm0z}OEj2MKPSkfkIF9ATZ9Rdhkbjaz1o=kNfk>rTy$bew2 z-F*NN?ev%Ggx)lL_NMNkjlcnMbL5OkL1@(pUbr?E0Kb%gPWr`_ucdNC`JP81Hco3L4?u~gbb+7Q9F(Rp{E#gF^uLm zo_0?gd))ASy|z2S(pJ-^(m_Chrza(d1~zW(v&55zFc*#%VdyaTdO++KUX@B$rEpDh zYOXuN_}&DnIUOc{GhU;+k21a|l~yUi5g?2AkoVzMQ z0fZJw+G>0)M21w_T6+tJ84x&~FooA%rO!wZG{$ov#OG+l(j+l(1PDFGdm#uKv2>A? zztG6iPBeL8)NA}MpYJt;SS;nrX*IEA4Lu7Xu7-vNw*BRYkwypFK}e0~7MwFamfPA? zy4wkAd_vCnlGCag9~j^T+oAOIy8wt^gSCJV;&8m!lGCagA2Xmgi&Qfp_<>ds*1vyP zr^Oi`Ghhcq!Gx?5Y|6UQ7ovtgHy*kApTzhy<(3v&hXc?GLT5Ly`U93lq+5UaqEt+P@PS{bmf``*3QoeT6B%v~!1LB)Usgj|1tC=5F4 zf67t-t4z4wGR*y0NZ+#xw9s5J3l`7T3yvt9N=B|Ko!*ZFe?Dq)HDUD1!L4CF^5*Yo zv2VTS1iyUzdI08;d+ihcRU%!((_d!JV!Q^VG5;8$&ooYQ-aO!jmrnLyzVF`yNM|7=;>c7`wWG5`Po07*qoM6N<$f=$^9hyVZp literal 0 HcmV?d00001 diff --git a/xui/imp/button_left.png b/xui/imp/button_left.png new file mode 100755 index 0000000000000000000000000000000000000000..6901c55e01ac5f541f4b12488b8e36c598902d94 GIT binary patch literal 118 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1SGw4HSYi^&H|6fVg?31We{epSZZGe6x8r^ zaSY+Oo}8AD5D*k(WM)=YSZG=OZH*AKvj+3wYBn}CHkpJ1F9rt5eAZQb0SjgT^)Pt4 L`njxgN@xNAM0y&R literal 0 HcmV?d00001 diff --git a/xui/imp/button_lower.png b/xui/imp/button_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..f08242fbea89e4b9dcd66a199172ccbd7b4afcf7 GIT binary patch literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1SGw4HSYi^&H|6fVg?31We{epSZZGe6jb$e zaSY+Oo*a^NfG;AZz{B9trAA?cWlNVPZhw4lZ?(mn0Hup!3@Za!j_2PLKL^yn;OXk; Jvd$@?2>`ALAUXg5 literal 0 HcmV?d00001 diff --git a/xui/imp/button_lower_left.png b/xui/imp/button_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..7e32a2353cffdf22efd661919bb6b667994805ab GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1SGw4HSYi^&H|6fVg?31We{epSZZGe6g2X5 zaSY+Oo}6%iQ9@EeA|@tg%9JS+T+`3aI(q29fr9t%6zasI%Ed5w;qo+oeIxN-F8(>FIa`|wyCcrb;5VHYRcOs*X}KLPbH Nc)I$ztaD0e0sv|9BhCN- literal 0 HcmV?d00001 diff --git a/xui/imp/button_upper.png b/xui/imp/button_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..004d9066d19ce8cd94f1a94846ad8f6a8960710c GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1SGw4HSYi^&H|6fVg?31We{epSZZGe6jbwc zaSY+Oo}6%iQR4EYOB=j4+}T~uznf20Rh4ZLgRM!EXgIOFvr#pomBa{kksK{vHB_nGrQ2a*;@HfJaEA9q^oU_j_;sibUE0XJ!yl z*Y8mh$Byho1XcZbW~QpRgSe~+Jo5Pti4+0PIYUH-C$3V@_G#U5ynXVO5(z*dqHa*l zPT#6f|M#e1*PScIHRYK31DqQI*#xJERGF7V&Q+eb8xRpFXH<9spa59)i-al3Lo(+m z&quQ5>w!($EeQpn9q?I759@$kXg6p{Sif`ABWwW+7or}S zx}hb}leoIh+goZkboYbVx(N7vpj3k}c`g>evI^e2A}y5|so*`m1@EQdt4g%sqaaMG zT5ON^^b6a7yx_}g`N$oSYxxY^HJEs^BPx4%G}|Sy0uK$RQ37{7{A4(Nbv*wArH3q& TO(?NV00000NkvXXu0mjfFk;KQ literal 0 HcmV?d00001 diff --git a/xui/imp/check_box_on.png b/xui/imp/check_box_on.png new file mode 100755 index 0000000000000000000000000000000000000000..4414b36afaa0545e8bf79f8959bfecdd8f652fb1 GIT binary patch literal 490 zcmVqOba259_Dj1cN zNGB#>7%*hr@%WMo;&viu_&&)&w&m=xq1m24I6%r)_-dY1QyB>F`XZwud*zWdx zr9=U65|NoyGw(+g`u`CX^tye;xR+e5^#%Mf5cpEb$;@5mC6Rqq=i>%MgrC;X;R%2M zc!>NXp<1#_X7}pcldT>HwC^$@0RVc2SfSaxMDf7KOd*4W{(sdcwzso-Ad$803ZQ;_ z-)0X{2fw-4xrdV`UK zj(cMUDKB*cOE)5mOy5wGuq5uGi_Vrl4a4(bwk`wybg1+sERlo7r>uipN2H|^o(fU# zHMmuVw<8mtc|ULzxy&#;RA{^MuDnxcuT%txcOU}Be62K;E@b`edisr127h@PiSSnrh5-@Aa zl$6(~Ef4R02Fa|xDf#&19b9L-&Lo$a*YBg$$d^~rE>3US| z9VN)iCpo0)yH$9n<^p7@h++tCyxX@3bbX;rH^|G?vXpMd!yXi@ws!TUNa7;Z<>(uJ aX+8nFMW>Y!6e7U@0000LZ6uc literal 0 HcmV?d00001 diff --git a/xui/imp/end_turn_button.png b/xui/imp/end_turn_button.png new file mode 100755 index 0000000000000000000000000000000000000000..57cdd8009a47ea0e9c907b72de103ca2bf7bd44e GIT binary patch literal 1066 zcmV+_1l9YAP)|AoBg=s-8PzyEqn7z3MT2Kp=u(Uu6 zDj|DtP%tqTpn+(2Gwf45ZvOu_ua*FLJ*wdi3sFPU-$RK3PEs-SDiy~OYJg0%NzR`(CRkpqzvA6&V* z4F0%B4TRt+T5DX4!Eepr0jbCoL>eDB#D^GA3LzF=W5q)tb@>=X8XO-re2)jDAY%xv z!mB+XH}-RxVK0O&FRFK&Va2!vWMr z_gV<8^OGR}T2osMgxn0Z6vFO#KwK(w=JhQIp$0L=tb33t2)1G<6`mGFBg^4fJQ1zW zOsm3D4|v%lJaxs;u%6{`3_9-V9EjZjt_rx=GM9P=p>;_tCqCCPF$k6=v3NaT4}_*T zvmrhQVqGUFII&hd1j5QsD}>eG z*Rm{cz~`>Xvz?V`n&6x(I^-awgmbR>Y*26U07TduJRF1(;@4l1bsY{h79XhSCH@hB zE)YtDq^HS3{CM`=z2b9IVG$P;TPH9=BS#yDcp!g9h%F|R&L6^=qWF5}9Hwdda;At& z{8lk^NKfDt|I7neJfZe@?3Nce=UBy;mcxhegm7<8@kJN3WQUgC-^vKR4om+Wmv3m# zfBnKl5rm$0gjZ%ZA#_cH2YG4gDTJPOq}S%M5V{V5WaS6n{Nm(82)*rSug=~<7-1h? kaHyB3R|tcOLAG}P0k2+==Lk#b`Tzg`07*qoM6N<$f*}*)$p8QV literal 0 HcmV?d00001 diff --git a/xui/imp/fill_bar_base.png b/xui/imp/fill_bar_base.png new file mode 100755 index 0000000000000000000000000000000000000000..11b3869e6fd494c4d6639051347ba6ecbe16f58e GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9EHPk}Jwzul4c?O2?!Wrc*UmRomM c-~k4PH5a&d`d>{<0vf^K>FVdQ&MBb@015;s!vFvP literal 0 HcmV?d00001 diff --git a/xui/imp/fill_bar_left.png b/xui/imp/fill_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..47e2044f4863d4a3e3d874c8052e1bfded4a9cde GIT binary patch literal 1009 zcmV2>8D5wRKKJ^e%dA+XjdTqa?%_Vc+**5<&fweSvkSt0UdV!x!LJfQ_ zJ}l&U0!`rPJ6DAlczGNwF@Z>84HWPoxBKa!W~~D*r3YwAjSfz=@~_1K9?zNtd{?t}r9XmzR`vR$38>W^t=b{i4Z3V77YAgp zv<9@&eZ8J{Q-BEJm>lVJ|mEQMoC3auV9Kbi<|`2&f1K2xCWk+ zN(Bxl0ukZ;B~O4Rwjko;K%{oFg@loT2rp)&%tkF4xzrHw_Mv zpaCMwWl~M;UMqMaK${A+?XWr~cv=s5iy8@!_8p;OiqxJv`7R+Jp2}yBfPa6nO^7US zi7nm{*xU18F%UT&ho0VEPKSAVqyH}b`51*2rx7qMCh(v*YOV3O$4IQ3gpvxZZ<&5Y fA*8VbzPbGa;9UAAHqRp300000NkvXXu0mjf-;Kt1 literal 0 HcmV?d00001 diff --git a/xui/imp/fill_bar_middle.png b/xui/imp/fill_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..b133332e9ee2b2b5da0f72ac7ce835e2e0a01d0b GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1SIoCSFHz9oCO|{#S9EHPk}Jwf{L+47BnAxuwTS|=~>VxTb$p00i_>zopr08=0=)c^nh literal 0 HcmV?d00001 diff --git a/xui/imp/fill_bar_right.png b/xui/imp/fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..524795f5446de61c888c285e40a7a0df747e53a5 GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQk(@Ik;M!QGf#mqK46e@u%8}CCZ_KCk0bPw^$#n&xx76qSx-)TbF<994xrc7oJ-dxUS{z my<>*Q%2qr}PbyoppW#Plg0PpX|2Lpx89ZJ6T-G@yGywpmzej{y$DfO)R?T>zc1*&E6boFyt=akR{ E02#?13jhEB literal 0 HcmV?d00001 diff --git a/xui/imp/frame_lower_left.png b/xui/imp/frame_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..6b5338f771c421557e56e1fb7403f3fba09a3bfd GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`>F z;us=vIXNLA;m7(VOTOGcdi1G1GxOnkHj@KK92f%DHL!NysGq|X6BAP~yWssj+cjYZ eNuQ;R7#Jo#<64$tB+CRegu&C*&t;ucLK6TYmnhx< literal 0 HcmV?d00001 diff --git a/xui/imp/frame_lower_right.png b/xui/imp/frame_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..d324d703a5e61f75639e6d9ef2a13def4b009469 GIT binary patch literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`^G z;us=vIXU3~%m1lUru^HzW5=KLgoGdGk2o*{tZQg(Y@au`TJZj!?H(=(&PYQE28P5G)_gHNPfMU`22WQ%mvv4F FO#n?R98UlM literal 0 HcmV?d00001 diff --git a/xui/imp/frame_upper_left.png b/xui/imp/frame_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..82bcc9323038a2a0da7ab8d9a07c7ac3dd8b0845 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`m6 z;us=vIXNXE;m7#~_6-I=prNU02*eM=7?{7mySq4mQN%#0c!mTA!zob)2JNTp5``Hv RJ_7YJc)I$ztaD0e0sx{oAEW>P literal 0 HcmV?d00001 diff --git a/xui/imp/frame_upper_right.png b/xui/imp/frame_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..a415bb1fc33e199455ceaefb49b2dd56cd2c9629 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`{H z;us=vIXNXE;m7#~_6<9B?07Kc&gOJ}=F@wtzi;r;($sYHIk1dD?c@OgTe~DWM4f5*RDR literal 0 HcmV?d00001 diff --git a/xui/imp/icon_frame.png b/xui/imp/icon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..edc3346c7ae5b9f6471662b5b4de0dc0b2e1342f GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6s+-d zaSVw#{Py}m-UbB$my7)iC#`Lb(m55iO)TnSv*N)cF8sTyXIctPsubYMVJs60W<0}V z%&lMkU6|oQHNUPr`?}9fyW6M5Gbq14|Md1<>55xlLf`RipCH4?BH+LPC069uuTN~y q{md4Xt+@2F#0)d(zA0}${$WT^7V)3?Tkky39SokXelF{r5}E*p1w(HD literal 0 HcmV?d00001 diff --git a/xui/imp/menu_left.png b/xui/imp/menu_left.png new file mode 100755 index 0000000000000000000000000000000000000000..d391c22bc4d52d3035a5043bce0fb3a71a304675 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1SGw4HSYi^&H|6fVg?31We{epSZZGe6qNRK xaSY+Oo}7}95YW^Zxj9YK(1B5yna{vNl_BI1vr&z4%|4(q22WQ%mvv4FO#tk?7Lfn| literal 0 HcmV?d00001 diff --git a/xui/imp/menu_lower.png b/xui/imp/menu_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..b278aef5a180b6b5ad271d5611bf0b2b843a93e1 GIT binary patch literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1SGw4HSYi^&H|6fVg?31We{epSZZGe6jb$e zaSY+Oo*a^NfNzF`$J7Iy5|=Ms+TgX}&hB#l-F&L5s+Zm{Fr>A!Buu*CWdPK`;OXk; Jvd$@?2>^@x9)$n^ literal 0 HcmV?d00001 diff --git a/xui/imp/menu_lower_left.png b/xui/imp/menu_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..7e32a2353cffdf22efd661919bb6b667994805ab GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1SGw4HSYi^&H|6fVg?31We{epSZZGe6g2X5 zaSY+Oo}6%iQ9@EeA|@tg%9JS+T+`3aI(q29fr9t=#A= literal 0 HcmV?d00001 diff --git a/xui/imp/menu_upper.png b/xui/imp/menu_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..6bad65991d7205095da523484e949001a1ea4e2c GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1SGw4HSYi^&H|6fVg?31We{epSZZGe6jbwc zaSY+Oo}6%iQR4EYOB=j4+}T~uznf20Rh4ZLgR zaSVw#{Py}r-UA9eE*JfesLX5KXxkm`*`+aQWl*Adx$0S46|Ou6^WK>ZX>Bv7PT&2T zo1vrQ(x>-_jOBM!XZ~dKkZk|G-Msvw3?qwx0|Sgm`1kj=H)HnNNtbMxZ*NPSm$>%x ZAI6$yVXyQu6CI$%44$rjF6*2UngHEkJ01!VT0I&0J~EY+uoU7myzFI zpZj^4vF|eG2{#Os9XJ>TU$!OpL^_1-e)#lIb7{iPkKc|LEnIcSkDnoJ=Du@#YA-v! z{}b-uVsXFt+-pN6r4?G|y|>xyU-s%?x!A$3i<|ae=Gbo-_3gW0BEzKcDM!mH!@e!n znj9X<{U_$0SVm*o+-isL1l#we+9-#9XJYD@<);T3K F0RV49XvqKo literal 0 HcmV?d00001 diff --git a/xui/imp/scroll_bar_middle.png b/xui/imp/scroll_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..a0cf11cfe44d4049b7fb0bba03ebd02a9960cd5e GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9EHPk}JwLPx# literal 0 HcmV?d00001 diff --git a/xui/imp/scroll_bar_slider.png b/xui/imp/scroll_bar_slider.png new file mode 100644 index 0000000000000000000000000000000000000000..216040c67d6e194ea8dcf7850fdd514281747cc9 GIT binary patch literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%C&rs6b?Si}mUKs7M+SzC z{oH>NSwSk3J%W507^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10g0sLQ zvY3HEPZ@+6E0)@q0R`DhJbhi+U$U@@nXwxPiwy8}e{Z-P*5S z3}3EA86E4Xvv@AHK5}Z#eF!z%2maN&u5o7_*@GJwtL>%esujU!9TB~g%8>vmtfhvEW+Q@Zn{g_UggD$_b@1J zOJ8N`DYz`eZn=d`V7T%Oeut8?T6zzTCKt@UQSjogf!EHn3`eHaODQ$%C}&u4)py#b zDICSSW~Cm!5f;-U!(wyssh!@vZEusLyBv}P92I5n39i`?^;qLwutJc?=4)%qMA#iH zI(qWzKAWA{6tL-ctUgTe~DWM4f D&L*sp literal 0 HcmV?d00001 diff --git a/xui/imp/scroll_bar_upper.png b/xui/imp/scroll_bar_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..c17f9b4fc3593f49418237d22046564b1573a5c0 GIT binary patch literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQk(@Ik;M!QGf#mqSo_rm2NC2^7o^ zdsmcxGjGLljtgNz?xCy-Q~tehao13tCCQ+)Nppi&jM5dM>nvRz8yzOSuq;kGD6c0! zQ}X#=)`mC}%}bxu?35GIV)*?}AHVzZV!wTd!0q?>UgjQV$NF76-j*LWiBX!=`|&Tw z=F)j@&WXR=n)kDM!mJ%3wnuo^I6nTqK&*TvxBsfUIgtfGmos>}`njxgN@xNAGEHI; literal 0 HcmV?d00001 diff --git a/xui/imp/separator_center.png b/xui/imp/separator_center.png new file mode 100644 index 0000000000000000000000000000000000000000..216040c67d6e194ea8dcf7850fdd514281747cc9 GIT binary patch literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%C&rs6b?Si}mUKs7M+SzC z{oH>NSwSk3J%W507^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10g0sLQ zvY3HEPZ@+6E0)@q0R`DhJbhi+U$U@@nXwxPiwy8}e{Z-P*5S z3}3EA86E4Xvv@AHK5}Z#eF!z%2maN&u5o7_*@GJwtL>%esujU!9TB~g%8>vmtfhvEW+Q@Zn{g_UggD$_b@1J zOJ8N`DYz`eZn=d`V7T%Oeut8?T6zzTCKt@UQSjogf!EHn3`eHaODQ$%C}&u4)py#b zDICSSW~Cm!5f;-U!(wyssh!@vZEusLyBv}P92I5n39i`?^;qLwutJc?=4)%qMA#iH zI(qWzKAWA{6tL-ctUgTe~DWM4f D&L*sp literal 0 HcmV?d00001 diff --git a/xui/imp/separator_left.png b/xui/imp/separator_left.png new file mode 100755 index 0000000000000000000000000000000000000000..96b219e8a147e6972c100219f7e37e72fc9e6187 GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^5{Xcce6p4h2YilBTUeqM%9$em`HSNI{M&`_hi6Wi< z_4M?3yu7?zX7YUH^gGbx`{CZ+Y8OeqVir60jSq|yrhb&0QpS!&6^u*JY`_qDlG-T|G( N;OXk;vd$@?2>>q5N`wFa literal 0 HcmV?d00001 diff --git a/xui/imp/separator_middle.png b/xui/imp/separator_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..9e3ab0e46cae8a7294db1ce5c2e4dcd83c28b9d7 GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwZe|HmK_A_9}^QxU;*w-$;Lt_VP2_J$ib2|Jko`PdRo-V*wKb ZgG(dNk{+Jthk^PTJYD@<);T3K0RTIZC9(hj literal 0 HcmV?d00001 diff --git a/xui/imp/separator_right.png b/xui/imp/separator_right.png new file mode 100755 index 0000000000000000000000000000000000000000..34f1936b7404f787474c0c518cf871e7c3a67b63 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwZe|HmK_A_U4@3oOU)TVQ2Y!xyV^lr%X}Mi%8wmo^m!ZJysyj n;n@UHwkK7MSsM+wRxmJVyYP#}@|+d|n#SPi>gTe~DWM4f*{mx; literal 0 HcmV?d00001 diff --git a/xui/imp/status_left.png b/xui/imp/status_left.png new file mode 100755 index 0000000000000000000000000000000000000000..9ab40e434621ff47d6b2c9c4e875f74c6a4d4cf8 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9F3${@^GvDCf{C>Z1E z;uxZF{_VtroCh2@Se`%8+Gx?eX~$|+{(~Hr{GU##?-NNYjbu+qI}p{qFGRGUyz{3| zxI;zcrMIv1&b@u<)&9G8!6L!t-S(-*ydhgAGb-=ayTkKE>`(oVfBfRJ;?kyuI!;^! Pw1>gd)z4*}Q$iB}S4KNs literal 0 HcmV?d00001 diff --git a/xui/imp/status_lower.png b/xui/imp/status_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..df5aac98abf9cf8aabfc0207b6660a0efc114c1c GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9F3${@^GvDCf{C|K_4 z;uxZFe(t1;yayCGT+Y8@T2rvupxfE7d-IMa?JtLy$b0!}#y@d<*TBG{%oq?l$@}1$ zm^g+n_r$G!$IQ!KyVjIJ>66GYiB+#YY436tn`mx0{kW`$oZ7w08xLn4H!_}d`f99P sImgNWg&x6g7TcUO+Wa^7oQ;6F!Xn2v9Ogw0KqoMGy85}Sb4q9e0QT}m0{{R3 literal 0 HcmV?d00001 diff --git a/xui/imp/status_lower_left.png b/xui/imp/status_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..02247af94e7e64324cbfff333448027c382bd183 GIT binary patch literal 597 zcmV-b0;>IqP)*lTmQeYM5EVg)$nPW0GhG7UtljtnfDR3zfA}X?T z69Y)Ef8Fs)hii6}x#X9{Y;Sq6|x*5@S1 z0jCQsTGC$U1ls0&AScKgaAm@Nf6vZarQFhXBrJHE+~F>$F&W)^J(t!tBG{u-p(R5` zc^Gl`Rh_c@0^mbGhzPv*aLz$QAR=(i#e4F~a55Fab0XaP?FK*~T7Jp4p|0DriqR(F z1$dv<;9D&n8F0?UN)<$pX__GNv$-+*nF#=pub*Rd{R&uxJxvpcXo0ctfs}!gIoapZ z=TnQe)#^(shtt)HhnXXtxp|-j{x617-HMzkwE&vh;Zt8oTh$+(jFf@qQ4?@3fm#hT z-uqBH-{oe)TMEd%t9QF18Ot~Oe5?AB2zR%GnWLrZ`PQkp)CJX=*s5-?dLr8NfvAZ` j{9!HKuNj}iGdE$93~ z&LbjgO-;>5!XhG+Qf4juX&xB^wLCi9*HN71=O4MfP}4i=@W8= zBJ@Zu7MP|EUC*tr#~aCtQB qZUnaSSNnWgZ`MY#2R>`7qyG;T#dI9Q94tQo0000Z1E z;uxZF{_VtroCh2@Se`%8+Gx?eX~$|+{(~Hr{GU##?-NNYjbu+qI}p{qFGRGUyz{3| zxI;zcrMIv1&b@u<)&9G8!6L!t-S(-*ydhgAGb-=ayTkKE>`(oVfBfRJ;?kyuI!;^! Pw1>gd)z4*}Q$iB}S4KNs literal 0 HcmV?d00001 diff --git a/xui/imp/status_upper.png b/xui/imp/status_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..df5aac98abf9cf8aabfc0207b6660a0efc114c1c GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9F3${@^GvDCf{C|K_4 z;uxZFe(t1;yayCGT+Y8@T2rvupxfE7d-IMa?JtLy$b0!}#y@d<*TBG{%oq?l$@}1$ zm^g+n_r$G!$IQ!KyVjIJ>66GYiB+#YY436tn`mx0{kW`$oZ7w08xLn4H!_}d`f99P sImgNWg&x6g7TcUO+Wa^7oQ;6F!Xn2v9Ogw0KqoMGy85}Sb4q9e0QT}m0{{R3 literal 0 HcmV?d00001 diff --git a/xui/imp/status_upper_left.png b/xui/imp/status_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..dfb727fde3896d90c104371e7f8091aeb96228cd GIT binary patch literal 546 zcmV+-0^R+IP)0sw>%Kt%2{wf(UM9zp;!o15i*SDs>3aw`b;4BWKi5Q6CjX+W9c8jRWvKY0tT&KjB~qB3Gj=9)z5|2#zy zu?1Wm`$kJ9xk_-Rl-|-wNOQqZo;7+|bK=JYbP(3+M34L~0iBMzKFC=9?DfNGE~wRkGe&TifS&DiR(M2C kOT+RzujOM?5&6gke}5f=mjVWQvH$=807*qoM6N<$f`U@*`2YX_ literal 0 HcmV?d00001 diff --git a/xui/imp/status_upper_right.png b/xui/imp/status_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..618735b5c731f578d5f402fd8a9fd9306341be39 GIT binary patch literal 599 zcmV-d0;v6oP)ycHGOHM z44g&!z?s3!D5V&Qy+&eQ*A=Rok|?DNgZsIjL@m{~s}M$TdHk0O89$#zx*{<#^G-x4 zrGSV)L{0FTX0nL+b(tpSk&}CESlVjoldwlE9kYqhw9o<{s)P;_b5HnUX=Nw2LqvVF zNX)%qe`nN4JQ-07Jf1#A!9;0-&WtM)=0V^p?9mBT75C3)0v}&=B9S?$#}Sd-2Yenm zsepff1iC%`FMw{q{ZsMr^}j+MIX;Ng?EH3BhM6_eiCPh1ih86G^6>lyPafd04k?AHjykiR>s1Y+(~6|$_CA*bcJ99z0dtAHQ% znTb$UA+#Q1^dxix{>mBrRMKJZ+tqhHZV*ZMyvwqJNG}cSvM21ZV(S;Y^~Mle>PD;> zuacnD9lW7eVV7vJ@;2Gr?$pUZrzc; l08ImX4qf9j!jT97d;^!7_M>?T8|eT5002ovPDHLkV1g>~3s3+6 literal 0 HcmV?d00001 diff --git a/xui/imp/tiny_fill_bar_base.png b/xui/imp/tiny_fill_bar_base.png new file mode 100755 index 0000000000000000000000000000000000000000..1d269a30608d7a5184362646c8f7709b9d8a5efd GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg`npr$CtT@x&!cKtUT% z7srr@!*8z`@-i6kFdq!jnsk6)!`Yx!tgZcz;s%=<(T2C@&g^;8aQp5}_MCM22_dW5 i85E8#nIXd5@muDj#9i&r)klElFnGH9xvX2viE5%?ZB0I2G6@brHFOK^+84crpHM(IhR%4huyI5V5R zh%sW+Eq(+%m#{3&tWjU1;H$^$B5wy=0fZ1tW2)-=w^;(avOc5$24=6Smupr9|1>tt zd;#L343e2Mgn$_1qiFhGR+;(cb`tsghf*|EZzNJQTYbXUa$bv{6j|2>37loi`@|y; zST47~a|Ln|`SV)bPn)pik(|V~6qNqZ&Uf1gl#*}j18UTg&y3e3CjdfZHno}$yg9>) z2@{EA#+-x#Py<{6O3R{o-7hO4d3XI#oStdH>ew_$$ZrKdD7B{IV-v0RR9107*qoM6N<$f~@_*3;+NC literal 0 HcmV?d00001 diff --git a/xui/imp/tiny_fill_bar_middle.png b/xui/imp/tiny_fill_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..714591ce38decbb520c2da8ea22dbb7e16f2e587 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg`npr$CtT@x&!cKtXR$ z7srr@!*8cK@-i539O+|Kz1$?0lAJoZkUxs`Y(tt*j=GBNa)+|*Us;RN%D9i1zCTbH w&&X8PsAKg&Y=xGaLzkwa<}&8p`=2t%&%Gd9d`30lBG6a{Pgg&ebxsLQ0CPSsrT_o{ literal 0 HcmV?d00001 diff --git a/xui/imp/tiny_fill_bar_right.png b/xui/imp/tiny_fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..46e5b5f9705bdf9088a2ffe1e2415d2abdf01f74 GIT binary patch literal 296 zcmV+@0oVSCP)w{m2F&-O{Qk9wE?wHwTteMp=CV&9o z?wbj`g1S0*jAqg454bxEapw1kdM;5B_9iKDZHy$esue{CYxV_&<84K1r?rUSo%EA; zut%ke>c1Ws-a#ovo@WnDbuR)sdYyDHYMfP}Y28;Cq2jiH)4gbI*TdaZ_M(_lmkuN^ us$wjq{9W);=;x!aFye?9hyS+RxE@c{mSW`ij;mw<0000L1WVwFh*OKu z3V1IP^!(6zp7I%qhzEEt5{L+aJWs%TL_EP;Nl*x-lpyE)O(4ej0?ZLXL=|``E0t88 zAyEUb{|jyGb3|sr(>0O@2?R$(BEbPa5U3U4h|Geghl~`U`1J^vX!_T5^&KZY3q>#gQSR7~j^K z`K+S;*VsRSKSw|soSKP2GZt^FfZM@|h;J(>N31v4rNvL0f^VMQuOHH`p!GDWQ9)Xt zXn&f($7h7cy};vM4y*BOdy$UKrV>5iwEs%xddxNXP;aH}9p~~ON+j!Kt_{Nj0qG&L zB)rn;7~`9w9FbDWv7qV2r-sBzK~vY|ZOGI_NCA+-=xh=r@V(iH&OH?MSCP_d7807~u1E8D*k0F=&=@rmM)w~Poq0nu zBryY|O*crj-nBC-&7{-ej8f1m#58Xy#hht2%w|>4j1NsgbBPk#w>_5E`_Fn=*H&0P z6)g9&l$56^Vg1%(>0=LThmBLgYGKiFKmNJR7iC@Bsp57QjsO4v07*qoM6N<$f`w8` A0{{R3 literal 0 HcmV?d00001 diff --git a/xui/imp/title_bar_middle.png b/xui/imp/title_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..444f836d2a3e02c3e7c4f3474802788f8f9f384c GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^5eDz8teHDB;@Jp=d#Wzp$P!fDlR+# literal 0 HcmV?d00001 diff --git a/xui/imp/title_bar_right.png b/xui/imp/title_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..885cf7d9df2486f3f195475585cf48883baaaa3d GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^0zhoQ!3HEH;(vt$Db50q$YKVDnWsRQ@$tkZNMwn?kaC3Ba#e800`f<*O&v22D}E_d_I@9w-)@; zoHg-v_jm8Tb?@qL@BG2R!XcpG(7?dR1Y}%@|Nm`e!;xMIdB>&aKMPA*bFL1|)y@N2 O#Ng@b=d#Wzp$Pze3^@J( literal 0 HcmV?d00001 diff --git a/xui/imp/window_left.png b/xui/imp/window_left.png new file mode 100755 index 0000000000000000000000000000000000000000..8657ad3833304f25c9f81a122ed2939b33052daa GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9F3${@^GvDCf{C^+BK z#WBR=_}k#qyiSHZ#-ZvTbz&PujhHv5OzS(q6W1vCprLEgrx&Y#$V`}(EOgsbTAm^1 zEDwVMXRSw*%7i07E7s4~V=HI(oKSOU%beZHu8Z@ZmW buvvQciue2NSpFmcoyy?p>gTe~DWM4f%3fIS literal 0 HcmV?d00001 diff --git a/xui/imp/window_lower.png b/xui/imp/window_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..e6680faa7b1ec80c74245dfc2eb6c07aa355607c GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1SIoCSFHz9oCO|{#S9F3${@^GvDCf{C^*m4 z#WBR<^x4S=d6^A4SS;sDFKAuc8kM2AH=sMakh74x(qfl~g?x<%=lO$1+S63MRyB9H zury@Pi0lYgdbQWu>VE5wm8;g8DkVKzZFo#zqJVy+wbe{Zt3TT3gIN-im9^KOYq~no zw(hY)sOj^?&z0Q+XJsFsHB0__`pt_wtpDv>+`Gd%PR-PqAup$6`OdJQCrj>Klqm}4 gYxt$VaQ`dTJJB77O}%!p0bR=A>FVdQ&MBb@0N&zOn*aa+ literal 0 HcmV?d00001 diff --git a/xui/imp/window_lower_left.png b/xui/imp/window_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..131f1bde09011cdb15cb84ea4d065d2aa96f40d0 GIT binary patch literal 1114 zcmV-g1f~0lP)MW1TexN48FH*8vwupCoU@m+N<>ZtZ4+i*Rr;bwl#AOJ;5zZ}#lBqz6xJqoewE!0?V(-w; zWq1te?E}2`M+`B>9Di%dwr%?;5{CEy?>$&+54T83r~r?O+NTpx;{$NydzVoptSL}@ zWstPPk;f5lRRJ0OVI-_MK+ZX^)+Qge)*kabgph4}Rwb+{;1pO%0Z0a~Yf%9o{ZS+| z`v8>v?Bbm3vN|;RfRgOF3M!;NoP;JHAQ^cY94nWqGw*;?4g>` zB&dDBr|&QnJZ-C)I<DHriYNWt?dmKwcSUs5E*fU5~WfUz&eHJ?kK5+Ma&a-8%; zNkc+Q99Ux;o0O%+SU~?zbuRWiCocBF(Tw$luMS;PVkJAAQb0}4Fh({Fv@_G{YYm8) z0!kYqY)iMr^u@_Zso*p@!BVauHOEu)yEbQd%B1L($_D`-1pJ3oR_Z2-G_bbDqUMB% zHt_LnHFarZvmeNfPOd(-55SFBY%5PLZnSTQX@^psl#V+%ly7kPWGH!%^l|+djauu z=vh$q{G1|}*^brsynMK)f{>IPt^!;|_-FLIiq|tAFhvR8d-(Mg0HDvs>=D;bcWO(u zgyd8ZLU@4hS4L!nhA06^`TV1EX9udanuM4NMwQV&Y3p*CkzT(qon&k4M<+#}GENdd zz&ji}TrF*frS+FM7pQf4lKPK>k@r0MGh#s1rs&l717;9JNg6r&#+dmEs8xyfSFF}@x6V(J}l`Dw;yL?3;@7ddo^gSg|!w+Dg1hP z9sju+Ow$CV6qHg|-=WW@X~F?J2_N_x*V+vMtzy>%NK_G<)9)F044gae+YkCZ12@LN zT8m{_yz{lzP)cE%rXUghUVzgN0q38`2&4Hf5xXIPGQ3p|CCcGM&}Xd)IM=vHE^rAE zEeSZ&8dXYN{>_PLnxM6=x}@k{T9v`G*81YcI0-r6jWNNE?iPK(#k$rE9|<*lz@bIv zDdVLopzOOO@Tw520z4xI0dusgiy`iUQ73FJA(l&&^c=&8_JJ&RXlMy4wOg z#r#|0;ojom-eUg!+TES!8RIxcze_$r;sZKq=7~81N56Ab)B^9@59m6}vTQB~%04N9 zFInCWr|6{FciT~%2&GgK_|V1_T4E9sIB@r~tq?1KZq7%96ufIhLfP{X5hB3{TL$MDanG+HG_fUpH&WkI^_rp(ovFcDG#6G}PKu&kZ z1us=ujXq##pE=}Q(5C>2dN@$}j4O*@Kcs@2X^F+UF`>OAbcD_A8Qx+~a98m~z!w3Z z(8>zE=^@=%OZTFZ<8X4go10R~+rZ$&Y;Bey`?W+odF=g7+x4lm4xwDnRWosX_5ohm^9K3O*(C z7X|Pv$5cS;yF>}M1U}mblqf+O9|0Z!I<58D_1~d}g*z@KA*Y4LU#MsW9sv4~?4^!P za+8udu3aVtY<;&B{5t|-FCcG?m%Ia*8#TZKKxd4p@-}Da0Fy$Fs{+31x{u&$fCqs7 zd6=qXJGNIsP4EEF{dubMJ}<@H@x3igC1gtlZ_BT%dB6RSxo*akYO^P_053ib zmbAl4+Gtz_Ex=!Gg7iFn>tvWRp8MibAW==Cm$s5}#(j=a;s@ZmW buvvQciue2NSpFmcoyy?p>gTe~DWM4f%3fIS literal 0 HcmV?d00001 diff --git a/xui/imp/window_upper.png b/xui/imp/window_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..e43d5613a06b404137796f7858d1c45214606d68 GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^53gte1?R`X=-a`o79L*v^a0faG-j>=Lt*Y76xAV1ewL(?Xp(? zIrdg`LXYjcUmgBy`7B;_8Q+;H?d#%m|A4LhHm)c{@qa^|)5X70&pJdjb@99ZM!kd|Ihqc2^&y0z<4XugDH&r- z7YX?K+~9sA$8W2omQpIdNX@+W#cNYa!^iiP@x~#bS0%l6GZ!}vFV~J=o`C;e0kc&w zI|m$j>`N12jPYAuXx&3{e47a#Shv=me|rq-ff+W7fWtXwVvJ^#gb;%9-k*PeLnU~6 zUekbt&$nwU;Bd~J>v>9PNClMFwMp1#fS+mJd-L)h)C#6;CioE*v|?T>G48*`^QD}C zN$Tkg_nF|q)6O}u$2b`uNWh?^o#D2^^D#yvRSATRq)xEblHRx0nh*kcd|wIvagVHP zUO(Ka8i^8C^#W7D<8vjUQ>r~`-tP&4A@HvsPDB8lFAWF$jx7Qt3OKlHZwq`WPH_l~ zC?Uqk0&lHlE8z5eYrfY44=pK{EcKg~5~yxcO27fd3wWbM1XuPLaE$R>E~yulk^oBK zCdSP$=Jw9HCvW9MSZl>GkB1W_@DdU*@a(q@dHjH9L3r!{rdB;sr7Of4$gBk(U!UI( z{?E_BIpJ}S=5deTmPiV?xD;;1H4Xuah!%M02l6EgtEhAihXjsc?~|)QZElZa6wb?U z#*w}E{wXtu5Ke{F@<3^I5CA{m*?4tGDQ!DfX*sSq=eFJfvQlsgx*GD4`=TZ2{oWO0K9k5 z>Ik79z(Wsw500_gVX8}`wyZf#QR~I1b4uVbQQ!nz`hNYkH3`V;<-FUgb%Rn8q*el- zJBK17p9fS4sC9x8NokVM0#B(lBVtp_0oM##I#5l1^<)-dYcivX|mEZ zz^gSwH4?aCl7Bx0VM8syTHr->K1=;$EP)w4f3;EvN;z zpb|m}|I64o|S|55mBwFk0 z?DhZv)>`KvPWmY0IV9AUPt!EL8)EJs*!FirRDFrQ$TWet$2AJpBc}z&I*DC

D{LerBX?|&I(pndHN0+04uasIfT`2`x>l^J)AqKUdl2F=Z_g{XFhXCJN3reY7 z;z~(NI7|?BfsY!W6AQTZ*9y!%y-ACmP5kd38CD5P=y|8GrOu}@CI~){1*rh(@f4mscIj>i>T1{)^|&QkLT=R z2~8AYw1p5Nq7?XBECFMNw1L+Fz>>RdV-LYXi}&^^5j;4@z>n1$IV4cv`G46l;1M*R z#|Re@QtHjS!=kmpw>_TiD;4YF%1g{@3U~?e&f{o7#N()^P>ss2@kuz5s)I+K6 zo^o!?y0dTsx)wJ#9f^Qbb{1C<7S#oIZu5bC!8N7Xmy*2|sRLXom8syRYPdcgTxp)q ziJ@RhGoY<6f%pixu>!jN8*gNwqvQvVUGd1I#4N+H%sQ&fxz6u6WvDLLTN-W0w6(JJBHNJs^r3SXp&&AGLm zah?kFzO$FZ=1HZlkyv=U#UGr|S7qrO|YJ<<~8~XO9tI^r&oATL~Ag;|5 z!T&QC>r8j)T660zXcGyk)w!fCA-S%L2>h@0Z$*emkO0Zs6=(sWb5Zl9F40BA5!M5` zdn_R3ymR2njE=G((}kK}5;w))AES%+{MuWYc5CpV3RmIO7+`F4h^QEt|xX(dHR{PAoDCF_^g0$+M@lRl&t3&EZ~NO zEm;cx%uQ@_?=#i`Q4$12+PXa--G#N5p10%z|15RDE>beXI$|AAOr~jqaU6GBioKkg zZ9CqnL=s{|oOM7YH$(Rgy}iAOg7jGjY_tMki~o}B=&S=Okl+KJyQs4cs7C^DB3yfZ cO4R|s0rIW0qJkjGhyVZp07*qoM6N<$f}!JL>Hq)$ literal 0 HcmV?d00001 diff --git a/xui/kobold/button_left.png b/xui/kobold/button_left.png new file mode 100755 index 0000000000000000000000000000000000000000..459c94ecd1861649f22f74fc030778c894fe74b6 GIT binary patch literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&Y_ z;us=vIawqn;Me*i4-Opwf`a};{^pI{Ld}yV2{H2+7z!{Pc4lPI4q|WK-Rfmk^j#u<#5o%UTA8i+|ad$4}gN Q1*ng~)78&qol`;+073>JUH||9 literal 0 HcmV?d00001 diff --git a/xui/kobold/button_lower_left.png b/xui/kobold/button_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..8eea2c7a97ff2aca16b100962494de71a47a2b93 GIT binary patch literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCpRjQPb85=c*~!m*lbG)wV&qU;&h44P=haet zRzd0BIfhrKcBMqVn{c(8uhyZxF2PmTgXIIm)nZAbbEQTRK$96fUHx3vIVCg!0Ce^+ Aw*UYD literal 0 HcmV?d00001 diff --git a/xui/kobold/button_lower_right.png b/xui/kobold/button_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..d634f5153deeb9e852142f8d0dc414fc104e17b1 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCpzq z;us=vx%Qm3=m7@~my7It8yco%L{5$9Xx%8lx#Yz16;e6#3C!+l;auPHkl7cengKE`~n{K?lC Ppf(0iS3j3^P6@(?8zgTe~DWM4fiM}XZ literal 0 HcmV?d00001 diff --git a/xui/kobold/button_upper_right.png b/xui/kobold/button_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..88314ab4ba52b9a1892063dfbeba42e49c427f56 GIT binary patch literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCp?v z;us=vx%Ql)AcF#r^TqnYhSrD!PN|DowNoEOWElT_$eZ{;#zIp~c*X*!U4e?ZVzQTb mE-T(#=FIfsg7r^F2KFd%3C8@ZLTiDBF?hQAxvXNM8Hw2&#kx0%W!)4DVzN}R`r$ZP(qqqoqZ1`7{r|Sdwoev4 z(9-vsap$eN(#a`{rp>GA&|VUBDEy&Hi>PDq{O##1o(vvghps-@y_KaSw}k84nV3Vd z2S5K_c7A;^XFcnC)dbZ~_YGMM9BXRd$sgSQnU6=8BjHxNK}MSZ_m6J@+&25Yta!HD zpF7QDP&T*u5s&c|;k-EK1P-1?MFW<$0|Fn+tb}b^I^!Bu_*Yh{0eSfjvs0>44(ZO} z5PW#o`i{L*Cg1jxKfXo$+c;xOm`UN^bu&b+o>_8T?&_IC`lmCCRab{>iLxv$zy4XB Yzj^cbjMV{=z+hnTboFyt=akR{08d7P#{d8T literal 0 HcmV?d00001 diff --git a/xui/kobold/check_box_on.png b/xui/kobold/check_box_on.png new file mode 100755 index 0000000000000000000000000000000000000000..a4a348cee73dbd775f9d052628947b763ec7d1fe GIT binary patch literal 409 zcmV;K0cQS*P)kP5f$SFnbdjmkmN|UHT5BOkk$}3DNaJ@;PkBX_3S|s z0LB=?q{Js`2@uQFDa3cqA-u;-Lvu06hExVqOm8z|nzIs$y}yR8|4^ zE9!?ggd|Wc26XQxbb3PQSK_4r{}7=GQzqukZI}Jh0_+#!H2~(Bh@0A;YNAYtNpvUd z=}x`~aYh^f9#=2jyZGpRF~CtKa!U26C7uiMz|HXm_ySy>1GNTFb_R|H(bcdu=RnRN zvNhA66ZTH=6@b`*U{%r84~ol0*T$=}BzSm)CRBk)u4L%p{(Oh|$Wl7^&CU4swfxYS zlv*^gJ7-K*)-2jyYgn^beAk>7Te5^jOPN!1w>|#>wyoI#VU>(700000NkvXXu0mjf DGn2I* literal 0 HcmV?d00001 diff --git a/xui/kobold/cursor.png b/xui/kobold/cursor.png new file mode 100755 index 0000000000000000000000000000000000000000..642d25fd26ea0b5ef05102edcfdedc40e207201f GIT binary patch literal 391 zcmV;20eJq2P)99uqURhRP=prFZ{KS8d@bY%Ps$aLl~3aRgu`QXq5tq{~q{KtVHq`)4^51>qb(ExXJ+zsAHS<9Vc>3PNoJRT=;QEKU#;LBy?n#{f1$ ztU#fQ%t;+=#vgR_If$P7Ga@qi~WtUM2=-X%bCg;u~B2;N|-|qm% lzI2xc|uv9Jl}g002ovPDHLkV1lTGqSpWb literal 0 HcmV?d00001 diff --git a/xui/kobold/end_turn_button.png b/xui/kobold/end_turn_button.png new file mode 100755 index 0000000000000000000000000000000000000000..d758401b22f3f5c3bcd1c90c689f8fed88be8d98 GIT binary patch literal 1375 zcmV-l1)%zgP)%vbFc5}+GHO(!Rf#qw+myV5a|E9wxrUBlUx8QP z6}EMW)}2#WpcW7w3lJnV6U=CA(H6z;$6{Xufdhwv{!-9iM_xmBBs_m_K!;pQe-!+H z*X8|yR~%&t{Za4+X2s5st@2L%=-J12B8Z)jAyl(+Bt`D%Ob4k9hMue^gUO^{k zkT5;Ka}g|%6+vSJVakdSJ10MHsR-Q~_|Q5wAQ8L)fiNw{6|_i%knr|cjR;*We8`Ob zH6OAJ9tyby*kckALITu^(5-u_f-ksK zgk3YiQh34?h4)3^FeM`FCV<4@mBJq-LX`kp!LJoza{+SMSPS^IB5dXaQ|WDM_&t|{ zC=b}f?33c(@&uj+OY#Isl_(OR7G6^$0W?*Muu6b6@BpAmgAA>L*Ghvlt+Ira2;Elj zT!2~;w9<|MTZnMl3f>=YFKtdCk-@mhkMyRCCd3(MTa+Z*T4@HO4Qkq*rw>5l; z2qo~XMCkT_mxxdU-$I0wT^GET_J8`VsFq1ii*a|1ZfTtI33lRp{O99jKwa$C6*ni1 zaXB_m6ENawtiUdThh^&Bi}deH7*N;wv0o}eX}-U;6Rd#`hQTdF*g6c>!Ut1fi3q$g zk`ti>zC?r;@X=a;XM_F-?d*t!#Ts~t2t4eS^eaNC@F@b>0eBF><^wjoEbw^6JYAEH zu_P6i#{9MLQ2|0C@MI`x0SOVb(oYGW6o8As`)#qkJuwlU8D88GO5M}r=_bGJy+uo` z6kgI2>m?nbPz_*9QYS@rEaAJ2brig`P2Nj7Lb-c-TZvE$pZdE<0KX&Tz|U}ATZvE$ zFWGyP?FdENT{D)rzV!Mw5Mj-lFC9Om@YDPE7my*CPqVxLKp6$~Q{k+DnI>E?001r+ z?jq2HvjUV-+pPIf6m){$dCCO4P z{LAZD?Q8l_M<@n=n^^u~-BLYvTc)lT7^VX7l_>xUh!H&?{j!&#qwU*|H;HB9Tcni%%t=%T~0{}i@ z{(i#zxnO_+;S2>L!dU^suL1KsFWw%PhxY0{=O5zm3K|y-AWS$zK|$l=_F?^5s*RFg@H2PTe!7k7l55Hpbzzfuu%fr*P h1x=I3-k;&|`G51YkSZm+cJ}}P002ovPDHLkV1mGMe`Ejv literal 0 HcmV?d00001 diff --git a/xui/kobold/fill_bar_base.png b/xui/kobold/fill_bar_base.png new file mode 100755 index 0000000000000000000000000000000000000000..9700b8d8e6b9969fb63173b72f545a00a4c275a9 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9EHPk}JwN8XFL(I;yfoUF?z7lXbqszS=3Aw@`kLr?qpi{DuQL zi!%i-USa=!@BZSo{0U+gx|Y=%E#1kV5f^gd4*M3pb?yfbFf**!*}!{h@|s|vB@CXf KelF{r5}E)|JvSBr literal 0 HcmV?d00001 diff --git a/xui/kobold/fill_bar_left.png b/xui/kobold/fill_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..f476e095580e9671a27badd639942a0e0d096c3e GIT binary patch literal 1685 zcmV;G25R|+zGGu6)z6kztr@g@ z9zfMv@Fn`$+Uli)ZgB3OH#lR>43_HWPy%?+0W^4h>EKKCb0`6F&<1w&e(vB)^>Ziz zdeAK{Xq-jk?vHZ^ulvy!@KGexbKou92)woTE0+Y_Ps##5f`obweD`<&o?8wHx}P}< zIGTiN4mjhBIf4og_i_6$3A4 z{3A&ClndTp{r$B-2)EE*0APZF`E2lPfR;R7&;S5l(BK=c{d&J4JeCvA_}-b5g~K;o z`|s)Yf(8Nf+YRCO-7KI>OZ&lU@YdLVwq?`rO<95jA3z}Z-ZBjA{WlM`gi3=CAOuhr z_@yMUsq1ARBgD}pJh7)`-~dM6erdDT0uE^XW%Qm7sQ}P=-;-eBdMimqhZdLjQY6$k zxTW$5f}eDfdxglFndCKU;m~>l5v}f2E&&VI&t^A!$$WxIkVNfGLKVx_*i^IpKo=Tg z>tD{Mg&R25>%|YcIh|eqU6~~Y(5^nAiU<_LACHkBXFCum5ZuXSgZJLU(hwBc3!FQi zgesxZOp>4pSPb4;5D^UBbBsl7-oxdl*FcRx~TO-|l9*7IvI z*({~)m2iH0fgePH(j=5>dx8gmC-q|$!6%o4&IIoyq?bbp3)mBUG!tY?$jJnG6C)>G z-4X_;k}c`+wWzBjLaaQl6J}S%2Cr-IJ{z1MVY3g&$TZnWCkv|k(ybO%gPH{CjUziX zNfNfUJ;9HBK#T+c@7fzDwyQc4E(4#SrEkl{i%^#bO0%V?Ca@NK_x`eSI42avPKKl` zK}+AS?Q0L5!AnUjSYHf$$|vysQ;s4u*w^pYq%raH06huh@oa#fTmuSiZxO~A5E1;% z{TLF;GLUSBp!5XP=U~>$dwDA?*{Ira{}b09o7+ za6W7 zyf5wyYb?SoOy2+g=0^k^dPZn!??C7Fx#0gg{gLhPe!2cS_5o56;%cwN86oxwd`Un$ zPuK!}Zq3j6fTyDsm`5pnuOeCEik&N%0{_qXZInqa1)o%ebcwrWHzx*4*7rRLkxX+A z{C{8mEjA%ZMW_#5CpQRrk$N?`{v{{|Ek%`>=rN@slmUz7@$I3vWM zwG-5;vEG!~66zL*!5lF}TY|h&;JZGm*m;7~IRpJVgWo#yi!C6>5~k{Ot-#2BaxH)} zyprutf623e981UrFZ;>000v)b=2u%lY6kVpXtHrG$da|MgT;M{UZoe^4cFmbA%91XAZeNipI$&woQ;`6z&e&)95_quQT=l9ls fZG7}!=Kt~)W`^`FPQn`h&}-Ga+>g&3}u znjWxHTzlfUum_`Hl!Nn}UkvBZ++tuZd&_%8?h1R%WPXE6-;XE0tN(w>JheZ)%As!p Q&>jW`Pgg&ebxsLQ0My?)82|tP literal 0 HcmV?d00001 diff --git a/xui/kobold/fill_bar_right.png b/xui/kobold/fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..186aeeff2b4fdb2dabede9f976faa20627328750 GIT binary patch literal 590 zcmV-U0BNP1dDfys-6bPQy|z`DmEj~ z4;IBG4HzVmu)Up?+{!$=`On*TtgcNFF2$J5`fV}h-u{rYy?qNFHP(o{pISjVB(Wq= z3La;{t6&biC6QYWzHDLJu&z+Vgx1{Pdo%ALb#=brR5(=gY9)vMbJ;Rj!FR!Xv?4 zaJT;#L=riHQqPkHuJrggDZSIAhohXY2m~jWCz{Lwi@}Tbgf-`qoUbErBY_&vi}r+P ctoHBtKO^4hH~M{pH2?qr07*qoM6N<$f(H)_a{vGU literal 0 HcmV?d00001 diff --git a/xui/kobold/frame_left.png b/xui/kobold/frame_left.png new file mode 100755 index 0000000000000000000000000000000000000000..2992c775ecb491b0862c19df1a5c5380a44416b4 GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&P? z;us=vIawqn;Me*i4-Opwf`a};{=?O6)jd2O4V{e)5^`J&pRceAbe;8e0qS7zboFyt I=akR{02mS=l>h($ literal 0 HcmV?d00001 diff --git a/xui/kobold/frame_lower.png b/xui/kobold/frame_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..595cc282a9ca4b79f44c76f09a3b7a7bd5d00bec GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@Aac z;us=vIXOY1;(*491z+UnGl{9PiSJP}2+Uz+cs7;k@`v5ll|Y3Ip00i_>zopr0Dx8+ AXaE2J literal 0 HcmV?d00001 diff --git a/xui/kobold/frame_lower_left.png b/xui/kobold/frame_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..a9be1d153be2c48e2d86c82993a9496674cf8158 GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{DCpto z;us=vx%BKo!3G5$hJ#1>G8DH4Y}z4Qf>f`x3pmf8zvplJ-Au6{1-oD!M2@rT^_$DzSNr9oQor!^E5wp{u!?$FCsu?_8{an^LB{Ts5 D*ESlP literal 0 HcmV?d00001 diff --git a/xui/kobold/frame_upper.png b/xui/kobold/frame_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..df9b88deaecfb48f3bae42ff84f5a9a050191c2b GIT binary patch literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&7+ z;us=vIawqn;Me&E_6-__J0466olwe?p`ptCNSx+h*sFuOg)z4*}Q$iB} D$I==Q literal 0 HcmV?d00001 diff --git a/xui/kobold/frame_upper_left.png b/xui/kobold/frame_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..c6ffbf349fc98e50860094e0f533df2709d71591 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}{8L z;us=vx%Ql+XoCWS%fU$Lh(?`bX56A33*0L?-jx1JOx_q=si3W+cX`3_c!Q+U`hz^P kXT1^F^4Gm%`;oM?cjq|oW+%V;G$|obn!>2zaS(GxV&zMk`=rl_w x&VzwRUp;T8j+v(To(W%e+AopK3Hs&Fz`of~^3s*8l2o9%44$rjF6*2UngDbIEp7k+ literal 0 HcmV?d00001 diff --git a/xui/kobold/icon_frame.png b/xui/kobold/icon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..91d28b47661689f7b7309b1a8a0c1bc79b5e386f GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6rAJf z;usQf`0ezKf(-^7uJ$(%h;C}qHZappVGS!_(ao{Z>*NjO(g^-=@2SQ=b)Gb5+lLnH zQ>xyZG=*&-Le=b+CM$9+Pj0hNJP0j`REmp97l04&PVl zvYjMaz#y=*{Pu3GAC*B0tZ>xjyWUsi%)gC$#7`!*ToTx5<6_7ec-Cpk<@K+BvTl|u VObZkAt_Hf3!PC{xWt~$(696Y)Po4k( literal 0 HcmV?d00001 diff --git a/xui/kobold/menu_left.png b/xui/kobold/menu_left.png new file mode 100755 index 0000000000000000000000000000000000000000..b03f501a335c84143c8c768becd26ad784c0b99b GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{D5&S@ z;uvCaI$0zo;Ftc11xFYTr%R?8O6=A!)X>y46kwhqp~144tw+ir>p+4b1A`DVOW>L9 SGfaRw89ZJ6T-G@yGywo%`5o8* literal 0 HcmV?d00001 diff --git a/xui/kobold/menu_lower.png b/xui/kobold/menu_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..f66da0f0ca0008926bfa425d047288435a2be4bf GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}{5K z;uvCaI@!nD`}cVV#)PB=0zFa&Sq#iTaC&d`cMYS4zzL3>i8Iy1p-ruaSMJJOGU ZhQ8U&qju=iYk8m%44$rjF6*2UngB1HCa3@a literal 0 HcmV?d00001 diff --git a/xui/kobold/menu_lower_left.png b/xui/kobold/menu_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..bd5992a12fcf7c5a04610c427e02ad8ee115bb23 GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{DA?rb z;uvCa`s^h~-Ub7n)`$C9m^TM-Z#K~FaN-tATPQYxLEOXR#exH^)8Aas{dp~CYKtCc zYW&oRF(RR=lluC9Y6hquK68(Gree>I13j%1pGmt+Ok)pR@;PtrMgt{=*D!dx`njxgN@xNA D3{^@T literal 0 HcmV?d00001 diff --git a/xui/kobold/menu_lower_right.png b/xui/kobold/menu_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..8bcfeeb3ebac7c5ebfca54c410a17624faa8fd18 GIT binary patch literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{D46Z( z;uvCa`t78HybTHhEbPwATO7E*xddKw;@+}BH=t>s0h^&i%`3IMS>ya{u;9+3!xXT$- TAM;cYsFlIf)z4*}Q$iB}8X+OO literal 0 HcmV?d00001 diff --git a/xui/kobold/menu_upper.png b/xui/kobold/menu_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..ca8f63fb328eed1adf2ecbd80236013391e99164 GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`s8 z;uvCaI$0zo;MaKv#stGOkK_d>8ou*uQ>mlt(^QuZ6PstUE;h0*1>6&-Tx0oq)#or@(S(?OZ}Akp zG7}9Wtu9mPhsJuI8M~%g-KufY_+&Jj>)PCM0q?}{Ijn~EmtudbO!uqvN>Ht2sc5%h eyYupYgYbuH&tlWHueyN_W$<+Mb6Mw<&;$U39#VY( literal 0 HcmV?d00001 diff --git a/xui/kobold/overicon_frame.png b/xui/kobold/overicon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..f02a9e0e94417c14a7174cc18f58a2bd9c3ca50f GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6zukN zaSVw#{C4_5-UA9e%(-SSxXxVKXw9u%(()}@kz?%?C%JQz-QTG=Z0bChb3$C^xl7{f zIkpwY-ko$mcyY=Do*k-=+;Igv8eY%!=ZyMrZ*Q$^w)y|IeiaMmJkKTO`d2?|Uwf~W z_|e0GNoYa?i;4mx=Mt;ERpOHZpTx_1IUo5Xa8$*`lsnKb{rYEVyRAuSic!HQfX-s@ MboFyt=akR{0I+FI_W%F@ literal 0 HcmV?d00001 diff --git a/xui/kobold/scroll_bar_lower.png b/xui/kobold/scroll_bar_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..67755e3dc4f61184695336e464c0d80cfbeb23f4 GIT binary patch literal 318 zcmV-E0m1%>P)r zE^%$&%~W5uMsH`e_LR_>5DAg8kp#f^7S#2%W&mt+gn2Tb3@Rd+S)1NQ&bgcY7{QXT zHVUR-tPM#-L?`gafqkza2@}`(>e*ulMR5(*Vl5MxT-=Ey=hv_B-|9lN&2lWiyC$JWV#~2y4vX&RoF1W^uR?6$ddBuN zRml!T+H(zG4&I5>AE|{$KXC%iHf?j~Q^TEu+6h+E?BSOJ012J-z2M>O4;lHXwlP1{ QXaE2J07*qoM6N<$f=Doj@Bjb+ literal 0 HcmV?d00001 diff --git a/xui/kobold/scroll_bar_middle.png b/xui/kobold/scroll_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..84ca0b27983f4c5787a9eae87fde68417b994f87 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwI{HUh!JdwZ*SPB29Nc{8t?$H3Nyr=nrfB%v5( yy@u-yNe5Oih8Q%k&R405Qn<;w_+`Qh380-J{BI`K@5luj&fw|l=d#Wzp$P!wN;P@_ literal 0 HcmV?d00001 diff --git a/xui/kobold/scroll_bar_slider.png b/xui/kobold/scroll_bar_slider.png new file mode 100755 index 0000000000000000000000000000000000000000..67ade15afa31a6e30f851cbc10a7685512796367 GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6#VV! z;usQf`0ezAg3SsdF5>NM8Hw2&#kx0%W!)4DVzN}R`r$ZP(qqqoqZ1`7{r|Sdwoev4 z(9-vsap$eN(#a`{rp>GA&|VUBDEy&Hi>PDq{O##1o(vvghps-@y_KaSw}k84nV3Vd z2S5K_c7A;^XFcnC)dbZ~_YGMM9BXRd$sgSQnU6=8BjHxNK}MSZ_m6J@+&25Yta!HD zpF7QDP&T*u5s&c|;k-EK1P-1?MFW<$0|Fn+tb}b^I^!Bu_*Yh{0eSfjvs0>44(ZO} z5PW#o`i{L*Cg1jxKfXo$+c;xOm`UN^bu&b+o>_8T?&_IC`lmCCRab{>iLxv$zy4XB Yzj^cbjMV{=z+hnTboFyt=akR{08d7P#{d8T literal 0 HcmV?d00001 diff --git a/xui/kobold/scroll_bar_upper.png b/xui/kobold/scroll_bar_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..1f1ac5a38415aef9c4efc308e8d68e7ce17a6f78 GIT binary patch literal 313 zcmV-90mlA`P)q$gGR5;6}l3|SlAryqa-P8aU#zHNi0SOgV39F$N*1}jo0{3H& zEeo{CkC59`EMcAm$K!UrkOWYA$TAb3 zx7xLSskM;ho4D@Vbq~3H6L0qofJC}L+IH4}3fB4DUJS6^H>B>29|Tm^Gd9OT>};Gp zK&rU_EB_oPphjhzw5OxjAQX-CN?pb|7jbun>I(NM8Hw2&#kx0%W!)4DVzN}R`r$ZP(qqqoqZ1`7{r|Sdwoev4 z(9-vsap$eN(#a`{rp>GA&|VUBDEy&Hi>PDq{O##1o(vvghps-@y_KaSw}k84nV3Vd z2S5K_c7A;^XFcnC)dbZ~_YGMM9BXRd$sgSQnU6=8BjHxNK}MSZ_m6J@+&25Yta!HD zpF7QDP&T*u5s&c|;k-EK1P-1?MFW<$0|Fn+tb}b^I^!Bu_*Yh{0eSfjvs0>44(ZO} z5PW#o`i{L*Cg1jxKfXo$+c;xOm`UN^bu&b+o>_8T?&_IC`lmCCRab{>iLxv$zy4XB Yzj^cbjMV{=z+hnTboFyt=akR{08d7P#{d8T literal 0 HcmV?d00001 diff --git a/xui/kobold/separator_left.png b/xui/kobold/separator_left.png new file mode 100755 index 0000000000000000000000000000000000000000..fcca2e2655a1ff05aed51ae93257a606ebfc6d9c GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwzF2-No$)TwCD``iZoA#0KY=s3&xXUst=y1d2?Jw;Gm3S!_hCf*Sxnk z9G9HUomn*xQVzJ;ptKXa#Tn_#l=*Za5*4lhmV4$F_bS;gP&lew$8^aJn4juqz| ztlDmT{gXDNe#Ap72HUM?|mDtQ_0_dFKQSj>0p`*D_f f_ImdFZxfiW9V-3BI@_S{ET@A5NfEG^mH`>APxU4p_&?$l|Ag(Xgk fS*ra0ZybAqF=>_Dho$R))-rgy`njxgN@xNA?+`&Z literal 0 HcmV?d00001 diff --git a/xui/kobold/status_lower_left.png b/xui/kobold/status_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..3d3061aba8904d7b85bf07187a73db69b5ac62a9 GIT binary patch literal 596 zcmV-a0;~OrP)FwLlB5#Vy>GaMyxrQ46%77AS%H z;H&}1#)2gN2{SO+XIWZH0}-wG@KV*G_3n`$Qc6%&5Rv`9YcccMf(QUWL}2EFxT<#l z`1hOf`^`OZq?FK#v;ka&*bDa{a)fIT0}-tmKvi8kUlf>-Fk=(W&m+}^%ZTic!vJz5 zLf-;oqED`{-z@+TB1RAh(N)J@2PH%^s;{3^&w(it6k<6rf^I{!?0YX>t%8wY zx171(MTnMo?Yge!z!bL#+<`c|xZFmROXw;@d2#jZ`}8ij3USxIgU3vI5O>870J$H` zZJ8J1s(2Z_psGU_E_=f>i0l*DzP&pyyX}xCmy+xZBKyQXBHp{BZ22F>__UUt&K|;i zLgkR@3v>e`bX)s!@){~17{u9#R$efzIxmG))y6;(d9H%makR|JE56^%egdmTpcaXD iu5tn!Iv;<0bpHdU==fm;Ga!aFU)Xe_^u`S$}D&YBKpEF$MOV^F+xN@MEUwt!OQ>vcLxt4fSFHl5jp+t z^PTbe&QtIhqb)$;tti1GB1-tB1QtA{ba}`wfJelJ1FWCdjtZ46NE&MD#^ONGWB7J@5_3YJH$wiWw2F?+i3o zP6!ux{$BvL#PEoP2nGV0Th}Rs=vuoH4#0+gFJLwku7s68uHgVo_`ixUjmUxv(qo6u ziZBJtzi_oL z*5$LW%`Pv0we0TZ(r*#}4;(qOwYcipElb;T^lM(YIjHx062j?DW5 Z-27iAo;V+VGa6_ogQu&X%Q~loCIC{!M>qfg literal 0 HcmV?d00001 diff --git a/xui/kobold/status_right.png b/xui/kobold/status_right.png new file mode 100755 index 0000000000000000000000000000000000000000..2b472066342b0c6b126d3db596803a67a6596460 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{D46W& z;uvCa`fb2L-UALCi_Ypk;5zdtzRr6&fg>+ Vdal2J3nS1v22WQ%mvv4FO#nlIIzIpa literal 0 HcmV?d00001 diff --git a/xui/kobold/status_upper.png b/xui/kobold/status_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..8ba8817e9dae9ab55a22810a50821e3684c7f65b GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C|Km_ z;uvCa`s!szUKT@+)`$D=8U}EmXA-**B&)qfEQ^s_dtvdcd!GE0pB@pPBrfD+`0LSv zb@B&yGd{c3!Lek{Y892YiPx^)Ei7kHnOORA?|Q>yerzXp6h*veuQ~HZyVFvgVXdi= n-Mt509kr8|pWpH4zwzDLx#6?Z*}|BBwljFT`njxgN@xNA%0oqW literal 0 HcmV?d00001 diff --git a/xui/kobold/status_upper_left.png b/xui/kobold/status_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..4db83b499b3151a5f0f2d76950f92de990c79424 GIT binary patch literal 602 zcmV-g0;T;Ga!aFU)Xe_^u`S$}D&YBKpEF$MOV^F+xN@MEUwt!OQ>vcLxt4fSFHl5jp+t z^PTbe&QtIhqb)$;tti1GB1-tB1QtA{ba}`wfJelJ1FWCdjtZ46NE&MD#^ONGWB7J@5_3YJH$wiWw2F?+i3o zP6!ux{$BvL#PEoP2nGV0Th}Rs=vuoH4#0+gFJLwku7s68uHgVo_`ixUjmUxv(qo6u ziZBJtz?P)osYrLI7`C0EE5xI$8EcrrlCk zpxshepxw?}Od!CB8T?*CV?Q&V|B=4F(1nQZ_~9iYm(kuefAQW!L_kF4^Sf3E;XWd< z000pogwTMC$mxqeUIRW}!x=cd_ZUUG5O|bC4SYr-M_40qA)M{++crP3y;Wc z6rFPjAq>;8OqS6OJfGG&Dyf(u5khE$d7T9(xE**2wF4rDl8TK)036CQnM9wCWfmNO z4*sc~nMe%Fa0Wb!?Aba*-oG@mYg@&BoK&ff z+Cd4f7}d-Bml^#s#=MzNi9eCSUx|2vMS|c40};W^0K7&OT#~@tw*RMp3BSo={lmB! zsP?)mL*jK)@@Z#ljwo6;I!&kBdd*T+K6%qjY#xr zuSrDtYFwi`!c;FfBB7loo7K*~55P~m;fO?E9mC#n0^ShF_rZKEnH<(eK_rM}j#z1D?SAmv}ky*`x*N3SmFf{^NB))U?6WHbC;U6E} Z{{vY}O66k(s*L~u002ovPDHLkV1h+JNRt2n literal 0 HcmV?d00001 diff --git a/xui/kobold/tiny_fill_bar_base.png b/xui/kobold/tiny_fill_bar_base.png new file mode 100755 index 0000000000000000000000000000000000000000..e2e8b918ac834fb887e43635663c43bd6ae3c871 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg`npr$CtT@x&!cK*1PK z7srr@!*8cL3LbFaU_R_SRe?`;Ije4l1C!XTaMLG_-zMj$NiqmHp)tYJ(HS$c`)~!{S4Yavpvim?2nc(zbV&g5s)_*UYWiAR#h#~ O9tKZWKbLh*2~7Y_b2rNX literal 0 HcmV?d00001 diff --git a/xui/kobold/tiny_fill_bar_left.png b/xui/kobold/tiny_fill_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..72cd6af5524076c96fbc6ba7dd2875b270dc2f77 GIT binary patch literal 613 zcmV-r0-F7aP)E2!q@Va$D0!vj#3W0F;h^Hh)Y&gex5Y z@p*}eW-UC%QW4EkxaEka1xU}aEe=ghY?i_U+H1EQ6a0}0fZ6+xrEr71{I1MIjeuq; z+|y#+U4-ux%Q5|@6tUO?IXsSQ4i~u#P}NBhQ7Ay@BxN9=Y}dj8j4|vCczY8In05krQXf&=)L z`3$@(Vh&y|$5k1q6%jWiWAM5CVe{^mEQ&Bln#<+dQLcQ^^+WfnJ>jER-O7$LfhnzH zWqt9UaB8{EGf=|+&x6T7aWwnx!|AH{j^p`n8$JC%4vG*700000NkvXXu0mjfZ5R@@ literal 0 HcmV?d00001 diff --git a/xui/kobold/tiny_fill_bar_middle.png b/xui/kobold/tiny_fill_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..481637c0701318691c5c7ac135f237073da3a105 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg`npr$CtT@x&!cK*1zW z7srr@!*8cK@*XhYVO}4~(c`2s#c3nY(+w?7iX{erI^Iuy?^(E};pMrAJ>i-L{HzUG zZBYp}OG;QbmU%f#%#3PWY3I!C68cq4;=tRvjHUb$2V9@1^?dGhelb7budvi-<~F_- TFBhQ(kZlZ}u6{1-oD!M6_OAPii4+yE_X3$#EBX(2^j3u!?u(1Kc^1mA;$ zV1kWum(OV?V>^SiyGS4{FxuVU_xAfMek~Ti#Ts0b9{!`F31qr}jyoMO0J z?7;jBPiKw!{pJJIbybvdWzi9jC~)9;6_w!CnXFHFNPh1EXwqD|1biT(Xw5~$GvQk+ zdBh^zLIvpo!Ywol0TrVH3&Kk`QQi zW1HpRT`Sw2pzoan^gY4P*_%%?B3@f&iWKH_}(eWqHQpUsqz~6`8R>=T(YTsMZL_K7?kGcQ=002ovPDHLkV1j_v5<2~L301W7EK=<1BZH@x3_XD`8MW8(b ze1}Wi?{GoQNVG?Q58%=9nk3pIz#Guy|5_xPBfxvy(Al1ZcMP3U9=Dg)M6(4v!OHIl zo~S3l%vDJ=M}n78lSH!xJOD7<1H7LUz%CL5d(YL?W&%s#IgC|^4DBK@G{s{G%z<}b z4rC}xU=Il)kjitGfC1f0lgUK#G;-hts2=Hm&yvst0ud|$PI1xuZO#g$-~)IycmS|} zEI4o<84nNX9f`g7Vz#ic~Eodmh)fIV-NyrC0+c5)2n>zl7N18TiI?dYYtt2#ff{kEu;7e8<0K%Yp`pKsxVh-w1PE-1(i%q{e&YHQj zgXh36S@F(NR!W6bBUXXo4k57wev=h1^dCzD0qMAVNyt;&0)EkoC+AHfAR*mCLavkF z+B>D-cUkdFO|+fuZ!UUIup`g1RM@F&)ZS?g_*4L9y%Y09Nv%|MB4;8vx zF88$f1WW+0PN#HX>*ZE_NT*i2MM^>E zbRSr>;)xhExi$WrPmu{H9%!cll!i8v(UKv|EU`4D4;3{@tg_U|xF&8yS3NazTZUi5b@ufLka n%fHa%Zc-xg?9e2(e1iH9RMk2ROce?400000NkvXXu0mjfc0{dM literal 0 HcmV?d00001 diff --git a/xui/kobold/title_bar_middle.png b/xui/kobold/title_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..9553b37ef6f7e5960d6774ebdf52b2c283f57360 GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^5zkuL${u|8S8f+6l)B~~S-~ZOWbr%#~dV;0z4$wgip00i_>zopr09c4q AJpcdz literal 0 HcmV?d00001 diff --git a/xui/kobold/title_bar_right.png b/xui/kobold/title_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..4042ee7fd5f139a87717768402b4d59a00055a07 GIT binary patch literal 646 zcmV;10(t$3P)#=swovr{ZH%nS2vt-#u;avamIg+rsF!4zU=9n-zM-J(4rR& za+eGg5x5ulNI(QD;36LJ-l*PH18oWp--32N5RC+VGUkRWp6Gc9-2d-f$ATd%!VxfT= zaQE&IBUu79BsMdUI$#cb0$Nm1^6ZF2Rs%8kY&r$tw~%sOap z`-m&IsvnrFRDMWI8N*lbTrdFpBtDs!21SD+Rt~`reITxg z_-aloVv+8k*gv)iyvPYlNG$G<2s|~hO)EaS3#@>5+az*=D*>I%>hI z`+>dV0II>O`hnOd;!I3FkseVAc=dRmw&Q|bSa!TGZO@Cx^W4N7lSsPf;@P0Nb)wmd g+QH;k;wPioU(3?%hF0u%i2wiq07*qoM6N<$f+PzdasU7T literal 0 HcmV?d00001 diff --git a/xui/kobold/ubericon_frame.png b/xui/kobold/ubericon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..73d3ab9d9f00a6fb1afd218b8945fcec71447e00 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6fE*| zaSVw#{C4_5-UA9e%!O`=V#m^^t-ItW;H>KLsbHVS&T5wvdAgMkYFYfDLc<@f-Xn8`XpkRoo@!`9YIbGU6+1~N0?>hQmSA@>0Rjc{WzA-R+ zCOnhR;<(9fUYm+i*~wR37oVE9>Qd?5Q&VTGUvpOKwVD~DqNoBv$Q^41f0Vh$c~=Tl)m>0mU02TXmK z&U0q+<%%EC^LS!TIz-Or-)286_N2qpN8cqaq&&Lj?fH7+$&G2r$AF$@@O1TaS?83{ F1OVzZe#!s< literal 0 HcmV?d00001 diff --git a/xui/kobold/window_lower.png b/xui/kobold/window_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..aa024d6cc567a21f9537b652b0c21c1ece523379 GIT binary patch literal 557 zcmV+|0@D47P)j}hjvRfsvM>X4I(kz=eZ z3D8tx8OAD@xnaJQTSPDyLor$bunqq`-ZC>p1m643M{}_XK;Uad82kZK{)7h!gb-fB z06J}<4q!^NkJge1h!v7H0}qYWY~qA zH$KF!I0otX0l2m@)`w=98j`-S!bAXb`#5LMpKy8K=)H#}9usudH(%dY?tRjqoYp9@+G vEGNZ9395je33~@q{)AUgyn5pQ?uowvREV0)-Nu^*00000NkvXXu0mjfelY&| literal 0 HcmV?d00001 diff --git a/xui/kobold/window_lower_left.png b/xui/kobold/window_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..10fa07ff953802cb411ec4e6b249a3a04aa6dce4 GIT binary patch literal 1792 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 xOTR@sn`gW#IQHfctp<~HMoGT>_&2Vh;0R&UX z;LOblhCum(sG literal 0 HcmV?d00001 diff --git a/xui/kobold/window_upper.png b/xui/kobold/window_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..de0988fdf15b23443f135f84d0f143516c19ce87 GIT binary patch literal 288 zcmV+*0pI?KP)}jN7a=8pw~P0E}#h7wFP4{Js=`b&E>iWA_6lbo9j7fW@Pgq zB9pr_&ocn-P9_f`GOg=+*b)(Ba;3BCJ`CpyGr7M5e_z1RTAP+-K~)hE05bV%!C+=n zw(V!`?m#iKt>-!}*G>5MH(>!#)lF3&2IQOCw_-$;@!cnP|7g;E1wUQI?~+DD`D6j^ mezf|f)2ey1keTb!@9PfrmB0=V>BSlV0000^#xJGiRu z?)!N6e7yTxaOYfGK!hJz4!$BHhgTtJ!9xhuL!Jr-$I1qd-uQy z;h1_S_RXI1MA^3I91ieAQ&P*^S$t zh;rFCI~-iCjysRD_j~L{5!kKdV%_h`uozrr`_9jmQN(;)LVXdJ+IMzeK7psBIv$1N zDm*?jKj6;in@QUfN3)|mXT;-pJR8o}I@-60txtp`=nNc4pWb^^^)X#(t1%q0Pvl`K zXGiaZ6|br41K<(Qgk_S9?5UdvV!ud@t5N48cqQP<>sLA7jjfX{)_fFE!mA_MmC2U_ wOL*^{poAw6lqch#vfK+T_)frYS`QBJ4*`rljYJYRrT_o{07*qoM6N<$f?7f_(f|Me literal 0 HcmV?d00001 diff --git a/xui/kobold/window_upper_right.png b/xui/kobold/window_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..22c0a6fbe058b2a67d7fe021db602d4b2336af66 GIT binary patch literal 661 zcmV;G0&4w)4-&!f9M~}n`07Qh8 zQU$K6PyhJiJ>la$Jp)IK5xqzofvY4+;AbRqgj*yQB6?&3sycP@y8;0bI}YIdyipt2 zN2E-L5y+7c5ioO4OxQ&c5OIe>Aw~cIb|eI*N$qMC?*Wk(rTF z>ZW6zETa>6K5byKRLqb_DOJL}&4Ls71a6^bV3%a6I7lRbVee!TJ{{{UIDj_zmv&|% z(JjLn@RP`PRQsnS)>&|cRN#8oYX6i(lfVdEKIH^HOJdjyN|Px|%!AWL$L6{W<@4|a z+6fe>Elf@02<&pGd;^)$w7?P0C*e1qiiEfATL}&TcPQ>Sp1sc0W@Rd^nV*`P}Q*}J+paeEOo_&|#%@k||>vHCP zJrc#X?+4(mcHPuKU@{?&NchcfJZxOkMwCnF3W*XtH?H0tVQ56>68i4_nFRQ#`%CtH zwHeJs;(x&_0{K3euVu3&u7dlrUR8C;!2WJHB9VQfOwr8A{cU^AlZ$6IB9VQfjEL_Y zBXcTA+}!x|@Hd^3g!zO@rS#lCj^D=a=_jwH@q&>UjcC5V_v+jOtE!EGB66;RRyulS vH49!Irkuc<5okr?Hzopr0P?FI-T(jq literal 0 HcmV?d00001 diff --git a/xui/main/button_lower_left.png b/xui/main/button_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..4cc4d888211a74b4800bdd776e31c2b79639a8f2 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}`&C z;us=vIl1QhySw#@ii&OJ@9!CMaB`X&Enrk*V`|{zl9(vl$-Cizgp-rg4$%jf&K@{$ afPo=pnPAL^Qk6!a2@IaDelF{r5}E+aF(hmN literal 0 HcmV?d00001 diff --git a/xui/main/button_lower_right.png b/xui/main/button_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..67631b31b81e0bb3fc516bffb3845a2976ee9e5e GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}{5K z;us=vd2ioFUIqo8!$DWLKN-Zl5l={RT#-}Jo2sh9E6Z?q8-uCs4+R#3{KIxLx1Dxk cTDpOOja^`A!S@TkKqDADUHx3vIVCg!0PWW#r~m)} literal 0 HcmV?d00001 diff --git a/xui/main/button_middle.png b/xui/main/button_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..e59eec4ccf10b3ff02709de7422396b6dc89df9d GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@ALX t;us=vIXNXEAtT`c^9%`&hKCCo7`imYc)I$ztaD0e0syu|7Nh_G literal 0 HcmV?d00001 diff --git a/xui/main/button_right.png b/xui/main/button_right.png new file mode 100755 index 0000000000000000000000000000000000000000..ecfe5f5664ff10e5c721309311fd0ce4e43fcdc4 GIT binary patch literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&h| z;us=vIXNXEAtS+o`Tf1UtHp(ck}AHxlVuiWW;C!7VPHt9W4l>rJXHv&oWax8&t;uc GLK6TJH5$zT literal 0 HcmV?d00001 diff --git a/xui/main/button_upper.png b/xui/main/button_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..58fa8d14af60a7685d48f542c77948aa795e75c4 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&n~ z;us=vIl1QhySw#lHVqRS8yVL#O)GzY&rrZ(`|H8!ROJ}w5EbsS2{?5ey#EexKn KelF{r5}E+M^&Bk# literal 0 HcmV?d00001 diff --git a/xui/main/button_upper_left.png b/xui/main/button_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..84850a24eb06b75bd27104782929e1c34e7ddec8 GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&r0 z;us=vIl1QhySw#lHVv(fjg5{T9vu6b*x1Umot0tIZuV(< S-Fb#Utqh*7elF{r5}E+VT_4f_ literal 0 HcmV?d00001 diff --git a/xui/main/button_upper_right.png b/xui/main/button_upper_right.png new file mode 100755 index 0000000000000000000000000000000000000000..32b178751cb95d2a3e6f9027a7035a16d2347f17 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C}{5K z;us=vd2jbd-UbJrBQjGs^Ae97ihH>71yjlUQFauByX420$Wm37-LQ77Sv0l%v1DFl>DWDB&w zOC`)6a3UfRxc~^q?3}wMGXUTo)~gnt%EaRZho=ne0gq)uRZowG_EZ9PPvBYMrxJF|0!>B}}_Bby2sQexm zl4gl+@HL4;ZpJYQ0Qau{2BAcEcqnlg{B7bNty+P`-S;*z00000NkvXXu0mjf5S5Y^ literal 0 HcmV?d00001 diff --git a/xui/main/check_box_on.png b/xui/main/check_box_on.png new file mode 100755 index 0000000000000000000000000000000000000000..46d48ee7f084c2cb21fcf63f52d277f5e6ae9f39 GIT binary patch literal 348 zcmV-i0i*tjP)evRDT_(Ceh@pCf2Q7Q#QeQK^W_i#0000NN|vPD#NmkpQT#8un&DJZde9$=fH zBiYq)ymcan+cze^<*UrRE0!dfC474uk|J8TY=Vbh&7^2`uA9%dp3IhCY+arvAJZBd zTwmE8rj^stsoj5mLG!NJf)^`#R#b)O?&bXFsi1W9*Q<>te_pLCl4yKmxjS5Tu4E7+ mf2D@X|M)dJ4O%B6zA_kCo)cl#y}T9ZUItHBKbLh*2~7aGBwT3# literal 0 HcmV?d00001 diff --git a/xui/main/end_turn_button.png b/xui/main/end_turn_button.png new file mode 100755 index 0000000000000000000000000000000000000000..62e857bd919482a77581dcd763c639a28b41df6a GIT binary patch literal 729 zcmV;~0w(>5P)vH*U8+f9t6#n?%^>3L7 zpb~5G?)GPRL`;bIBf&GK5(y6g6*^49GSa1~-S7$i0{#CPcQ}m1x=51R5u6IVh6DiE z5OHnAt2P8U@Hf{cLJp8-^-VH#iUxekeha>l1G-b#UALD=D3S0_(4G>CHGBo4=776v zEF~1J49;0}cf(7U%F z*8C{I^2t+0P{1`MWbba@N{m|fY)8nQLyH4MaKw zz9jffgWp2PZYgY03~9nY)&jF9MlJYeHCQE_kFREsKrM&QvA4?MZ$sqU68knqhXQ-= zwz!7`*MpJQAC0x%{_;E=)r6<;kji1on-;{y(;5v=UI;}<@P=;+kiK&xm0$_qlHPks z%0)sHd{@B8+gDTx*6_V+3t{Y=N{EE#%mPC%BT`<2r5tiI0E{VPc`|#EiC{gwZN* zBv!Yhv8O4~qQsq2z>|bXc=CP#2T-z!A{g^-v6{76zC0Z+AsYSK) literal 0 HcmV?d00001 diff --git a/xui/main/fill_bar_left.png b/xui/main/fill_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..718b784a74c757d04b79fe740bb22d2eac2d2c8f GIT binary patch literal 413 zcmV;O0b>4%P);@z&3lKtJ zH?xEU!f;L;Fah|F4dJ~H-uwQ~-~a-E<0T~gaETOLNQ6V-!!vM<#02OH;JQVk$%PY< zJO&YUQO+gKsUnaApOcWss|D7;OC_3`@DhopHhk?f(d+?Vs6;2vslDI;Kt!D!IT68o ze@RxLHaurK;tK5BMn&{}{}}g`D36jIELE-=qj%0dnfc?Fz$oFI>uX7*;9Bc{r%;!``TMJKq3zmYJU#ztcS&6OfyD4cf*4jHWzeXcE>`y2F z2*#MtXc1bpWiLwOxds4Z%)M>fx21L8Za*S5wo|6WZUg)Qdq}9_u3LFr00000NkvXX Hu0mjft--TT literal 0 HcmV?d00001 diff --git a/xui/main/fill_bar_middle.png b/xui/main/fill_bar_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..09c77427e8bd95d7622d43b00558d198525fa0ca GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9EHPk}Jwz;y7s#SY>BTvja$4L2MRRWZ2YY{1;XG`Zl>fgsQF4YwT|nOM2@ gtjpB@{QvYG|62YlD>!GA08L@=boFyt=akR{0P&wJ5&!@I literal 0 HcmV?d00001 diff --git a/xui/main/fill_bar_right.png b/xui/main/fill_bar_right.png new file mode 100755 index 0000000000000000000000000000000000000000..7b0d2b3f5bed8f1969913857e2b599906f897425 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eL!3HGH8OdY;Db50q$YKVDnWsRQ@$tkZN zPZ!4!i_^(9-{0M>XVY=;@aUMx$o`|B_pwn&XCu#t`6AH~_x4t|zsWmvOnEj_>f^1g zCH4zuJDd)Ao!@2kdSa-bwg_dBM*bD5&Qp-lK1(53K=|I{an^LB{Ts5}H literal 0 HcmV?d00001 diff --git a/xui/main/frame_lower_left.png b/xui/main/frame_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..a72209e74a8d1baadfa2afdfd417793222c1c3b5 GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&r0 z;us=vIr+!`|NraR*xLRFNHH523NVxe9B4Xo@L9kPCO0>?J8BO;C^CZp!}@3ej+4)e RCIhuHc)I$ztaD0e0stgCBD??q literal 0 HcmV?d00001 diff --git a/xui/main/frame_lower_right.png b/xui/main/frame_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..e6ce5ef483060d92750a197c6c856c465ae173cb GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&P? z;us=vIXU3~)4%`!|I2&*O;1u_c(I^?^_9XME(u9V&RGrNj11;UD_| literal 0 HcmV?d00001 diff --git a/xui/main/frame_right.png b/xui/main/frame_right.png new file mode 100755 index 0000000000000000000000000000000000000000..f13c0c1df50b65ea228a17205b17c9d6d624e140 GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@AUa w;us=vIXU3~)4%`!|I2&*O;1u_XlrL;h)CdM>rikx22{l0>FVdQ&MBb@07Ru3i2wiq literal 0 HcmV?d00001 diff --git a/xui/main/frame_upper.png b/xui/main/frame_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..18360527867dd035a7b66fde05a7c5af99562069 GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@ACU z;us=vIr-23|NraRY#JsuHZrbf5@TZH;bmZOF=qd7#2EJ)sE)zY)z4*}Q$iB}dYu_Z literal 0 HcmV?d00001 diff --git a/xui/main/frame_upper_left.png b/xui/main/frame_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..0ceca8da120252798ca6a8b3d6ee4ff6fdef6ea7 GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{D5&G< z;us=vd2f#)AAm}8FW&F%%S~)B})ylATLC{@CAqK7Nxlh-z@!N3--b%7 literal 0 HcmV?d00001 diff --git a/xui/main/icon_frame.png b/xui/main/icon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..0f1db5c2d227aa3d7c92960573e13e09c3fff15d GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6pZ$C zaSVw#{Py}r-UbIA=Ro;WERhl$H-tAl65&+5sCKq|YD}^I(&=xbn>jsCotbz(H{U^b z?#jiFKUbK>)?KT~umGBY00Q;BOJxm01Ckfb*!P(s@{LH`wWU+ELGqrielF{r5}E)v CmNYy7 literal 0 HcmV?d00001 diff --git a/xui/main/menu_left.png b/xui/main/menu_left.png new file mode 100755 index 0000000000000000000000000000000000000000..ad04d19375c822514fee5562b478eb47902ad1a9 GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{D5&k} z;uvCaI=SZiySw#@ii&I!72n^H$rV$2MMeC!LBJSo`? P)W+cH>gTe~DWM4fmAxSW literal 0 HcmV?d00001 diff --git a/xui/main/menu_lower.png b/xui/main/menu_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..664e5509737f0dfa7bf56f239c67e4f2fcf8aecf GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`;E z;uvCaIyogFAtPY{gMncHha0biX@eGn!RR10)(s1|6{O8f g4mGsO)GISHtePp9V=(>cZ=g90p00i_>zopr01_o9L;wH) literal 0 HcmV?d00001 diff --git a/xui/main/menu_lower_right.png b/xui/main/menu_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..8fb6a26ebb4314f5c7f9f471912b4079bf860bcb GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`v9 z;uvCaIyogFAtOOSXixR`b#WdZ95c@!IO3ovVVZD-VU@&zAMft&{=X!{!T*%b2_|P_ ho``#UtKBCuGI%Z(*m_Xcz!+!_gQu&X%Q~loCIE#LDjNU* literal 0 HcmV?d00001 diff --git a/xui/main/menu_middle.png b/xui/main/menu_middle.png new file mode 100755 index 0000000000000000000000000000000000000000..687c3c2c61fdbfe2224145ebc10e4a965f0e6827 GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C@Aac z;uvCaIyogFAtPY{gMncHha0biX~LC;gGmew-g*oRq!j~J0TnWMy85}Sb4q9e0AI!! AA^-pY literal 0 HcmV?d00001 diff --git a/xui/main/menu_right.png b/xui/main/menu_right.png new file mode 100755 index 0000000000000000000000000000000000000000..09019836e7cbc9cc340ac7f163de6328349542e4 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{D5&n~ z;uvCaIyogFAtOOSXixR`b#WdZ95c@!IO3ovVVZEIA&{A^n~|Y)65GqZ=8ic)EexKn KelF{r5}E+?MjwCx literal 0 HcmV?d00001 diff --git a/xui/main/menu_upper.png b/xui/main/menu_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..14685192061de77f321649191776702bb2de6f0a GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`;E z;uvCa`t1cnUIqi6BM!^8J}8*AiXHKvn8aYdF z;uvCaI=SZiySw#lTnyaI%*@RbCJ5YQGcXL`&@gLYjeT%;cli`a2HwfX77DX1X6unU c00aySJKnM{TXfOd3TOy}r>mdKI;Vst07~*D*fKZlnzXc$v4w40{()~? iHS?Z|+kI#hdceSXkZ)`EJ$px>K@6U*elF{r5}E*Y<0?b| literal 0 HcmV?d00001 diff --git a/xui/main/overicon_frame.png b/xui/main/overicon_frame.png new file mode 100755 index 0000000000000000000000000000000000000000..44a13fa95d75a09ae74c4dda0ec55339dd212997 GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6pZq8 zaSVw#{Py}r-UbIA=Ro;WEH~@j)-$kLwM@u({A~AblkbZ{;+4}nG?fWu$YX@w4}7KAODv9Fl%evZh!wXOG6LGqrielF{r5}E)8 CV>pxm literal 0 HcmV?d00001 diff --git a/xui/main/scroll_bar_lower.png b/xui/main/scroll_bar_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..6ae9c44840a15e44529855a1c62f7ce1a3754e84 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQk(@Ik;M!QGf#mqtFauByX420$Wm37-LQ77Sv0l%v1DFl>DWDB&w zOC`)6a3UfRxc~^q?3}wMGXUTo)~gnt%EaRZho=ne0gq)uRZowG_EZ9PPvBYMrxJF|0!>B}}_Bby2sQexm zl4gl+@HL4;ZpJYQ0Qau{2BAcEcqnlg{B7bNty+P`-S;*z00000NkvXXu0mjf5S5Y^ literal 0 HcmV?d00001 diff --git a/xui/main/scroll_bar_upper.png b/xui/main/scroll_bar_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..81fba3c8e38b8af25e57bb20062f954afd78a5c8 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQk(@Ik;M!QGf#mq`Axq4Siih>BWfvz%1nDG+$NmU6`XM1E!{8SsAS~GF@yfVC zdcm=tEgI74++pi}>E(CUZraVfzNswbts;ZN)=t|K$4(tCnq}^^qPf0Tpi?yJ3R}(r mb%t+xXH68UBP@#ps$(xNbv=^y%S;AnJArb9sh literal 0 HcmV?d00001 diff --git a/xui/main/separator_center.png b/xui/main/separator_center.png new file mode 100755 index 0000000000000000000000000000000000000000..62aad2c30e7dbe463e7714d8efa10115f3985443 GIT binary patch literal 353 zcmV-n0iOPeP)FauByX420$Wm37-LQ77Sv0l%v1DFl>DWDB&w zOC`)6a3UfRxc~^q?3}wMGXUTo)~gnt%EaRZho=ne0gq)uRZowG_EZ9PPvBYMrxJF|0!>B}}_Bby2sQexm zl4gl+@HL4;ZpJYQ0Qau{2BAcEcqnlg{B7bNty+P`-S;*z00000NkvXXu0mjf5S5Y^ literal 0 HcmV?d00001 diff --git a/xui/main/separator_left.png b/xui/main/separator_left.png new file mode 100755 index 0000000000000000000000000000000000000000..728d4ffab6f4a49ac556ecb93685e1556089e099 GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}Jw70812aRiBKv$F=VWQ1 OE(T9mKbLh*2~7a>BO%5B literal 0 HcmV?d00001 diff --git a/xui/main/separator_right.png b/xui/main/separator_right.png new file mode 100755 index 0000000000000000000000000000000000000000..6481f60e2bdfb916fd363986216b6a9279fdaa16 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9EHPk}JwpFB?lQ+ b5hjLR%;xqQ<*AK86Bs;Q{an^LB{Ts5)z4*}Q$iB}H3cS{ literal 0 HcmV?d00001 diff --git a/xui/main/status_lower.png b/xui/main/status_lower.png new file mode 100755 index 0000000000000000000000000000000000000000..3a59006a975d2a9863c93606a38b3c33d0285cab GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`m6 z;uvCaIypfi%ApOk@)(4_;+3=1py V_c$fEcmnk@c)I$ztaD0e0sz9QB^>|& literal 0 HcmV?d00001 diff --git a/xui/main/status_lower_left.png b/xui/main/status_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..d75c94a0979e8c4450cf352c1ba0cd2a38ec06e0 GIT binary patch literal 401 zcmV;C0dD?@P)9n0~{%_acTkPwmwIRDC5@qBAJ83Vo zgpw$b_b`DF2V;oHfQTR>fQT2UgovE8Iu3RS4=)arfQSqtl3pS(4H+Uji-cML5%Y7k zgje+Z0bWQ9hYRFz5djf-xYsJ-8+v{&;p01ClJFLI0aZzOE8HsK_kiz_iK*f+9zUn+ zsg&1CWv1V+%2ZiyB@=fd>RKc!@Yzl7>bHQ1PWeky zuJu;B$00000NkvXXu0mjf)f%VC literal 0 HcmV?d00001 diff --git a/xui/main/status_lower_right.png b/xui/main/status_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..e0cda067f380dd2fc26f370657a990f26885b530 GIT binary patch literal 412 zcmV;N0b~A&P)e_0iSnwpI4Y`lG+7wi76$Z{H?iU zsyJvVU(+}Ocr*<`uNYiJ=8fM88)4eSPjKAO%m^Um{{?g|~_rdcb=)5rqTz8R7NT zNW6QQ@9)-)7WkHkECD^>J5Hnp^n_)z4*}Q$iB}H3cS{ literal 0 HcmV?d00001 diff --git a/xui/main/status_upper.png b/xui/main/status_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..3a59006a975d2a9863c93606a38b3c33d0285cab GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`m6 z;uvCaIypfi%ApOk@)(4_;+3=1py V_c$fEcmnk@c)I$ztaD0e0sz9QB^>|& literal 0 HcmV?d00001 diff --git a/xui/main/status_upper_left.png b/xui/main/status_upper_left.png new file mode 100755 index 0000000000000000000000000000000000000000..a83439b67b1fca65bae08cc5eef2c5186758a0fe GIT binary patch literal 392 zcmV;30eAk1P)}(sA~FDQdYZrzUS|yeVu@h^M7)L&4hzt~cdmrh!q@6XCF~w>jfCBR-$Dp}1TK}Z z9rzSNa2$9?qOdkRB2M#UAxSjLK16gMN<^BOZ$$zTCu^oiEKu`j mnsB6Wl|YqHpN#MRJN^S^-ttyxd^(!|0000upziQ>F;Iy-X^{R8(p}B$#nU&w_S)- zsjgDLPhH10z<*y85k-xIbzMK_d4ARSh>|OTM*xV+vV1%|0*Ls>_TGOv=U#>Z0N^n4 z0ujA!#TmrOIrlu`&uGMn2#DxnJLmS^`{P{za^i>xhMle?bS@PgeqSq2+kGK~wL~2Gl|oh( zls+p$uuwI{HBn*F%~r8vuQ=b+yRQUsIR(a;{Uf_@F&`fA3u3ha_CQFV{o2hAT!WBC zh38Ax2vBn{nwZHxitWLbFwklw0SV`skUDOM55Zum{;Suq!ZrBSU5$~P{S`bq4 zp^2yjp%EXR33Cuz@zG^QUq}$Kl>>JJNDziYNWNSJz#-C?Pf|ZSO-n;W1Ind#pj|)a WHAz#-7z!Q$0000nsuZrZzJ%*7BDbgpCK0Kw2{i(qli0hLci@jwI1!PE+``O7 zgsinwj=>rDQ)~TJ3QtKGW5_u-RSB$cu7#&0wAM)p9u2RR;HWT`5%8P@fN8S}04yS+ zM!`#3H0}aLCj(CTS&X_YYu~QFzN6W3J%P mz`)4l#$0pqj>BJ7r0pQ$M&_WY>$3i-w?_OIf5f*wbFWLgpYzpr!t zv$t8>?$_(Mxa>K~zpUukLb>}n`>*L=Y~Q(oY2Jg)T}oj`X93;L;OXk;vd$@?2>`25 BXI20J literal 0 HcmV?d00001 diff --git a/xui/main/title_bar_left.png b/xui/main/title_bar_left.png new file mode 100755 index 0000000000000000000000000000000000000000..270bf4a10d92b172593c7d19c392b05a6404cba0 GIT binary patch literal 718 zcmV;<0x|uGP)Fc5~v2?(xj=UG9eWm)wg`m8?O7FbBQNzmZh zi9KU)7g0-l;a%DJe$OE@UV#7O6A$nGXpH&uVc`K_0)UAlLNFnw@H;8x=AO>E7o}8( zzq8gpYOODid4kh&f&ehZ#H8TyI{dNLK7A;7@BI|+)m#Jv{yDPl4gl`LJ)LuhDlw4o zar`^v#DH_|pp-hp>!g(X;8{Dow{z}UDRoX3;Ju$h*o-*|o+Cn>3jB(Q7raL}x>oSk z+NVE;n=Mn#Ll^IxYBG8 z#9h@i+Db$WUI@``zKKskMB?PXw=N}OBEI6h%_t>)9IKd%iMU}Fb3dDw)3roU;7L7k zre%smP~pio;G^`H*~Jc8(p-mYsX{9els?kc{lsSBwjKCe0KrE~yc!TVBNU XY)-Lmh;Fqs(0L4=u6{1-oD!MmdKI;Vst0I>ln&Hw-a literal 0 HcmV?d00001 diff --git a/xui/main/window_left.png b/xui/main/window_left.png new file mode 100755 index 0000000000000000000000000000000000000000..e87a3de134f97e360f43c3b90ae634a99bb76f09 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6pZn7 zaSVw#{PxO5UIs-T=fGm+iig77)vOsBN~g5@n%?VqO*2=@*#9HZ-v61n3E@-hbyk6GNMILgQlASt=F0 dcNv!(@w?|J`DI6bpANK@!PC{xWt~$(69CTDK5qa3 literal 0 HcmV?d00001 diff --git a/xui/main/window_lower_left.png b/xui/main/window_lower_left.png new file mode 100755 index 0000000000000000000000000000000000000000..389a476da5f65bcb73761b59f225581c57098cef GIT binary patch literal 793 zcmV+!1LpjRP)f15;R(OTc6l!Mm#E`$(L%0Yk%p>BK#mr{yD z#IF)y_AaCZ0zCPfE3{A&2nnyX7Fuhl1VX|aIRGYsknk2XL;|7V(Gmy=@5up8B@hxm zkOP`YASC<=bQ1}LhDS>vBz$BJs49Vw@KVZQUlhS45E9;i8qhuAsPN~{K6d=}E`)eL zyUuf*)rOS1nh2=TV3>qd0W}*6k&w{?iW|6#+`5nuD}WQ;I0r8wMnDbtZX{&hhy_0N znko`PmDYj}B-8d1d==J&KbcFkm5}gsSmDtUD0b^Qb$V;>|6Auxj(bfp(_QXqGkGjG zg-1%DUf@v@s3&-Y1VY7pFA|18qhat7dkwMoK4lnshHoK(b5F3@>#S|tKDp}R4uQ@5 ze~l1W*Y&?r>dF=Zr4`r>*&9e45^BOf^ne~EIO6^;r6i^&KRE^TBB2$$QvkDsFQwEa zMMC9aZ;DzAa7{CnQrC4|zpV3ay})~WfVK2YT_L)9!l#+MTn$3Np9&}lk0c2w_$&b> z5|(B8H;&_rJshFnvjuQUaI8j~!56(8jZBnJIbH=ytmAv;ZZw+!iirK8W;h_> zQ$~So33ivYB_QEbM}d-_5R`y|Po4_bkbs2GS_}9jL|$8z18S6O>W+{#6i$)CyraR{ zP{%psB?;hqtra5y@#I;S!yHRzBz#i=J_$(p=>32cz?|i7i&*cjIKD&teZ}|`4_3Yb Xp`A-8At=CV00000NkvXXu0mjfv+-A) literal 0 HcmV?d00001 diff --git a/xui/main/window_lower_right.png b/xui/main/window_lower_right.png new file mode 100755 index 0000000000000000000000000000000000000000..7584dfb91ad3910b96b8b7b2d198029068fd9c85 GIT binary patch literal 796 zcmV+%1LOROP)~%w;ao z7AX&oBg{F0VZgQl#p1nR0RRxuc<)z4ymr)eM#Q~y5T1J+8vuYo6Mk#dCPJfFZTLqI zfL|jZh7Top@6Z3WfEeC;58iuK304yx5jSWx304z6f>x1Wwc)iTSWWny7$7RaYQkq? zfS3fU34Z`BBEf3IYfG@2@P#peRf5%oM?~{j2&qZ1n(zUX(e4SoOWN;G;W1@h7XY}# z=UUsK2Hz_|TmT1rPu-#dsNlW#OXgh5HTVTk!WaC8L;{%r4tNO(BmxNGkGd+kgl+*` z@TuU%A)!kEC;Z+VPA#EXfCRjRgk0U0E4@9a=bBgzUK8o=n)qFH+FZRBkcO9#5FTd* zXu)equ+IdqA;CTyymU-3&j=sYdG5IOA%l5lcnJw)TVl(yd^fd6#P4P5X)VnE^i%aSAP zz`wM>r~ZiCG92dZan!Uk{92gmCMqy-NEFi^g%&>|tu1gYV-*Kyc}Kr|ex zcb2%}*<(Pjgql?yH9U)e773+~(^A8;38;~v3C}8kA_g>Mrq%0$p=7La&JIMW^Z6+E z7nufICG@WHdTzdmy){-D1B_I=MBf`Mi~&ZnO-Adz-JKXvyj&)@z5&gWc#iM)mEaLJ awekh*a#Agy2ioEQ0000($41 zYj-i|%@THCV4TA|A!M8TYc?x^osA4k910Da8FtVAD7GNEB2S@#fr+7lVd-HxhoCci QK-M#Oy85}Sb4q9e0G}Z^D*ylh literal 0 HcmV?d00001 diff --git a/xui/main/window_upper.png b/xui/main/window_upper.png new file mode 100755 index 0000000000000000000000000000000000000000..6f68fcfad189dd3f289b4f04d380efbdfde7886e GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6io4S zaSVw#{Py}r&I1NKE*FbWuteQBd8nRsxvw}UlU7YQ_wPp4mZf)%8?JIqxWZ+zYyJY+ z0;VEd^&H)QEkIX!}|FKNqqjL@_!7m!Ls}PYdg(srrF^GU}0dU>XqnB3r z>E4c+UFw`>3D#l%2*}LedVZGhPYOuE6VVg2wS;a@NS8h`Yw&B~Zz-W`Noo_22z*Y0 zc1{S5p?qz83|vhPu!w{p0nf~r+z^<8FUbMg5&{yw6k1b4(1xD@N^^jn+dQs z2WUv>knnRIkJsi#18E7lVNe}@9&TGC?3ub}9|0@)g@oG2;bM{mwc(Kx!cpK+5{mW% zwBT>I+pp8<^qM+XSm*NnwON4lDz60od_KQ!U1K4^BjAT&c<=lEXJWQ!F2MufKl;9Z z*_bk$O7KYdIhmDwR!f4ng1_JIpE1TR)xc?#fk?<^_nL)G3;bfJHJ9Lb_Ou8*Qi4~8 z{~cpI)r6$A1g{AHC&n0BGIK)0NJK$Hf|DLW1O1W8N8+5Wk7RCwCuo7--qFc3h;Zlc|N9nAM8d~aZ$tF{UI0$svlgYCIQ zs->!>N{!F4XU1_TfMFw|k%&h4iERQO0l-v(v${DVu7v<1x(s=>_jdpQr}aP-W*)Zg ziHJZ%<53BS*j0?-GXLx?;fV-{=syXXWAc{ph&V%=NjNQUt`+lZ8MB1>ce&xPT++EA zBc20dGatzTMG_FPBce;}wW$^5E#V_Mpmc?GC86Uj;S)Jvw}fpi`w|J>5JC+dOfM3j_SU8B}04{h93G4#6;jJVTjd8$F$?L5YekU7Agp1Wow8fqXy21pgjn+Pgm5&vomo zvd`+Vno5v_FBYIBL3-w^1V~HJSoYNdBqb=ueEox&j1nGN@T>x)BuK)u3*eR@4KE^q zQ-V~f6Bi&Qp|H=Zi2!a1rSLTZst-iC-a8cT?W<3mSWbj$C0N0;38;}^3C}8^RDvZu zyMPi2mhd71N+ejpiwVe)UN`fW4s(_dTOL%nw uTM{hcO$2O7(E8uSml3d(!126qP5TQ12wc%`xp{2>0000jMnU)w&&T#jtxCJcUuG)7=g%}@qGQeo4h7g++X^m tf~ETW+)l~%C!arheTG4;CTl}U$@|0d$sNr9ynwD?@O1TaS?83{1OU$MNMry2 literal 0 HcmV?d00001 diff --git a/xui/map_preview_panel_on.png b/xui/map_preview_panel_on.png new file mode 100755 index 0000000000000000000000000000000000000000..08dd569284cc2dfd49a289bbec82547e6cea65bc GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6s+-d zaSVw#{5H&y?|=eF@FVUY|D}I2#XURgtKyS%DNc2pN3td>!=ym_b6;4l&t?#v7*Lir z?^ED6j#-PlRmmP>l4#{*Ot_jmuf8x91RQ{5nL7jiqGdQxEQ&h w{>rRN1tms7?P%X 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 AiU0rr literal 0 HcmV?d00001 diff --git a/xui/palette.png b/xui/palette.png new file mode 100755 index 0000000000000000000000000000000000000000..8a8ab27c131fc01974627ef1a5083f39346ff98b GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQfx`y?k+$Y2!1;6t_M<_1s;*b z3=De8Ak0{?)V>TTSmf#A7@~3h?D>tp%mF+M7uk~-*BAUg|0VnbM}SJahl%E;gve{5 z>i60A?KO-SeQxn^37@*U)#){|*ES?i%e=YqaJuT9U==U7!$(>tO8G9EC;vzALhn%oc$@@B=5UY_ePsB7czopr0P9vr Ab^rhX literal 0 HcmV?d00001 diff --git a/xui/regular.png b/xui/regular.png new file mode 100755 index 0000000000000000000000000000000000000000..0e5bfe7e285393030848adc8626d3743c903644f GIT binary patch literal 9327 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 literal 0 HcmV?d00001 diff --git a/xui/status_preview_panel_off.png b/xui/status_preview_panel_off.png new file mode 100755 index 0000000000000000000000000000000000000000..fdb51734ab908b60be599ec008c9b7786c1d3fe6 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6m0f% zaSVw#{C1il-vI*-=7o>e+H{?tv{HI$prV1u`l(s3-*_wIgTe~DWM4f DA6Q5d literal 0 HcmV?d00001 diff --git a/xui/status_preview_panel_on.png b/xui/status_preview_panel_on.png new file mode 100755 index 0000000000000000000000000000000000000000..530fc12f183e0aea5107202f0ff7730c19c3bc3c GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6m0c$ zaSVw#{C3(w-U9|4%nOs4zRjN~dSbP`*J7s!fq&M9M5ntmC75K1S>4}q=(T1;m&Yn= zpw z)*d)CXCwD2iCY2^Op=Tue4S<&d=ZNOvS)e3hN{G0d!f>gTe~DWM4fMkhfy literal 0 HcmV?d00001 diff --git a/xui/text_box_panel_on.png b/xui/text_box_panel_on.png new file mode 100755 index 0000000000000000000000000000000000000000..0576c966d6e20681f00494fbbbf687b6b320bf1b GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6ioAU zaSVw#{C27%-vI>8a@w?8 zk)isp-M6xSD*3eA#p~3wbuK@)F)g3|W6^WlqfJ-2FPAg0#_=tyXn5oBD^_6Ye^v$t a1BM?{M3ZEG6r2Xy$l&Sf=d#Wzp$Pzfyg@1e literal 0 HcmV?d00001 diff --git a/xulkan.h b/xulkan.h new file mode 100755 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 + +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 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 index 0000000..ee77e9c --- /dev/null +++ b/xuxuxu.c @@ -0,0 +1,130 @@ +#include +#include +#include + +#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 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); +} -- 2.39.5