├── Makefile ├── README ├── go2d ├── Makefile ├── const.go ├── event.go ├── font.go ├── game.go ├── gui │ ├── button.go │ ├── container.go │ ├── element.go │ ├── element_properties.go │ ├── label.go │ ├── listener.go │ ├── manager.go │ ├── panel.go │ ├── scrollbar.go │ ├── scrollbutton.go │ ├── textelement.go │ ├── textfield.go │ └── window.go ├── image.go ├── rect.go ├── resource.go └── tools.go ├── screenshot_linux.png ├── screenshot_windows.png ├── sdl ├── Makefile ├── const.go ├── event.go ├── image.go ├── renderer.go ├── sdl.go └── ttf.go ├── skeleton ├── Makefile └── skeleton.go └── test ├── basic ├── Makefile ├── arial.ttf ├── main.go └── test.png └── gui ├── Makefile ├── arial.ttf ├── button_down.png ├── button_hover.png ├── button_normal.png └── main.go /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2009 The Go Authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style 3 | # license that can be found in the LICENSE file. 4 | 5 | include $(GOROOT)/src/Make.inc 6 | 7 | all: install 8 | 9 | DIRS=\ 10 | sdl\ 11 | go2d\ 12 | test/basic\ 13 | test/gui\ 14 | skeleton\ 15 | 16 | clean.dirs: $(addsuffix .clean, $(DIRS)) 17 | install.dirs: $(addsuffix .install, $(DIRS)) 18 | 19 | %.clean: 20 | +cd $* && gomake clean 21 | 22 | %.install: 23 | +cd $* && gomake install 24 | 25 | clean: clean.dirs 26 | install: install.dirs 27 | 28 | echo-dirs: 29 | @echo $(DIRS) 30 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | To use this framework, you will need to install SDL 1.3, SDL_ttf and SDL_image. 2 | 3 | ###Windows Users - read this!### 4 | If you don't want to spend time compiling SDL, but just start on your game right away, you can download go2d_windows_bin.zip (click on Downloads on the github page) for compiled versions of all needed DLL files and the two Go libraries 5 | ################################ 6 | 7 | Installation of SDL 1.3 (note: OpenGL renderer needs OpenGL libraries (e.g. mesa on Ubuntu)): 8 | 1) hg clone http://hg.libsdl.org/SDL 9 | 2) autogen.sh 10 | 3) ./configure 11 | 4) make 12 | 5) make install 13 | 14 | Installation of SDL_ttf (this also requires FreeType 2.0): 15 | 1) hg clone http://hg.libsdl.org/SDL_ttf/ 16 | 2) autogen.sh 17 | 3) ./configure 18 | 4) make 19 | 5) make install 20 | 21 | Installation of SDL_image (note: PNG loading also requires libpng and libz): 22 | 1) hg clone http://hg.libsdl.org/SDL_image/ 23 | 2) autogen.sh 24 | 3) ./configure 25 | 4) make 26 | 5) make install 27 | 28 | Installation of Go2D: 29 | 1) gomake install 30 | 31 | Usage: 32 | Check out /skeleton and ./test for examples. A detailed documentation will follow soon. -------------------------------------------------------------------------------- /go2d/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2009 The Go Authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style 3 | # license that can be found in the LICENSE file. 4 | 5 | include $(GOROOT)/src/Make.inc 6 | 7 | TARG=go2d 8 | 9 | GOFILES=\ 10 | *.go\ 11 | gui/*.go\ 12 | 13 | CLEANFILES+=go2d 14 | 15 | include $(GOROOT)/src/Make.pkg 16 | 17 | %: install %.go 18 | $(GC) $*.go 19 | $(LD) -o $@ $*.$O 20 | -------------------------------------------------------------------------------- /go2d/const.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import "sdl" 4 | 5 | const ( 6 | BLENDMODE_NONE = sdl.BLENDMODE_NONE 7 | BLENDMODE_BLEND = sdl.BLENDMODE_BLEND 8 | BLENDMODE_ADD = sdl.BLENDMODE_ADD 9 | BLENDMODE_MOD = sdl.BLENDMODE_MOD 10 | ) 11 | 12 | const ( 13 | KEY_UNKNOWN = sdl.KEY_UNKNOWN 14 | KEY_A = sdl.KEY_A 15 | KEY_B = sdl.KEY_B 16 | KEY_C = sdl.KEY_C 17 | KEY_D = sdl.KEY_D 18 | KEY_E = sdl.KEY_E 19 | KEY_F = sdl.KEY_F 20 | KEY_G = sdl.KEY_G 21 | KEY_H = sdl.KEY_H 22 | KEY_I = sdl.KEY_I 23 | KEY_J = sdl.KEY_J 24 | KEY_K = sdl.KEY_K 25 | KEY_L = sdl.KEY_L 26 | KEY_M = sdl.KEY_M 27 | KEY_N = sdl.KEY_N 28 | KEY_O = sdl.KEY_O 29 | KEY_P = sdl.KEY_P 30 | KEY_Q = sdl.KEY_Q 31 | KEY_R = sdl.KEY_R 32 | KEY_S = sdl.KEY_S 33 | KEY_T = sdl.KEY_T 34 | KEY_U = sdl.KEY_U 35 | KEY_V = sdl.KEY_V 36 | KEY_W = sdl.KEY_W 37 | KEY_X = sdl.KEY_X 38 | KEY_Y = sdl.KEY_Y 39 | KEY_Z = sdl.KEY_Z 40 | KEY_1 = sdl.KEY_1 41 | KEY_2 = sdl.KEY_2 42 | KEY_3 = sdl.KEY_3 43 | KEY_4 = sdl.KEY_4 44 | KEY_5 = sdl.KEY_5 45 | KEY_6 = sdl.KEY_6 46 | KEY_7 = sdl.KEY_7 47 | KEY_8 = sdl.KEY_8 48 | KEY_9 = sdl.KEY_9 49 | KEY_0 = sdl.KEY_0 50 | KEY_RETURN = sdl.KEY_RETURN 51 | KEY_ESCAPE = sdl.KEY_ESCAPE 52 | KEY_BACKSPACE = sdl.KEY_BACKSPACE 53 | KEY_TAB = sdl.KEY_TAB 54 | KEY_SPACE = sdl.KEY_SPACE 55 | KEY_MINUS = sdl.KEY_MINUS 56 | KEY_EQUALS = sdl.KEY_EQUALS 57 | KEY_LEFTBRACKET = sdl.KEY_LEFTBRACKET 58 | KEY_RIGHTBRACKET = sdl.KEY_RIGHTBRACKET 59 | KEY_BACKSLASH = sdl.KEY_BACKSLASH 60 | KEY_NONUSHASH = sdl.KEY_NONUSHASH 61 | KEY_SEMICOLON = sdl.KEY_SEMICOLON 62 | KEY_APOSTROPHE = sdl.KEY_APOSTROPHE 63 | KEY_GRAVE = sdl.KEY_GRAVE 64 | KEY_COMMA = sdl.KEY_COMMA 65 | KEY_PERIOD = sdl.KEY_PERIOD 66 | KEY_SLASH = sdl.KEY_SLASH 67 | KEY_CAPSLOCK = sdl.KEY_CAPSLOCK 68 | KEY_F1 = sdl.KEY_F1 69 | KEY_F2 = sdl.KEY_F2 70 | KEY_F3 = sdl.KEY_F3 71 | KEY_F4 = sdl.KEY_F4 72 | KEY_F5 = sdl.KEY_F5 73 | KEY_F6 = sdl.KEY_F6 74 | KEY_F7 = sdl.KEY_F7 75 | KEY_F8 = sdl.KEY_F8 76 | KEY_F9 = sdl.KEY_F9 77 | KEY_F10 = sdl.KEY_F10 78 | KEY_F11 = sdl.KEY_F11 79 | KEY_F12 = sdl.KEY_F12 80 | KEY_PRINTSCREEN = sdl.KEY_PRINTSCREEN 81 | KEY_SCROLLLOCK = sdl.KEY_SCROLLLOCK 82 | KEY_PAUSE = sdl.KEY_PAUSE 83 | KEY_INSERT = sdl.KEY_INSERT 84 | KEY_HOME = sdl.KEY_HOME 85 | KEY_PAGEUP = sdl.KEY_PAGEUP 86 | KEY_DELETE = sdl.KEY_DELETE 87 | KEY_END = sdl.KEY_END 88 | KEY_PAGEDOWN = sdl.KEY_PAGEDOWN 89 | KEY_RIGHT = sdl.KEY_RIGHT 90 | KEY_LEFT = sdl.KEY_LEFT 91 | KEY_DOWN = sdl.KEY_DOWN 92 | KEY_UP = sdl.KEY_UP 93 | KEY_NUMLOCKCLEAR = sdl.KEY_NUMLOCKCLEAR 94 | KEY_KP_DIVIDE = sdl.KEY_KP_DIVIDE 95 | KEY_KP_MULTIPLY = sdl.KEY_KP_MULTIPLY 96 | KEY_KP_MINUS = sdl.KEY_KP_MINUS 97 | KEY_KP_PLUS = sdl.KEY_KP_PLUS 98 | KEY_KP_ENTER = sdl.KEY_KP_ENTER 99 | KEY_KP_1 = sdl.KEY_KP_1 100 | KEY_KP_2 = sdl.KEY_KP_2 101 | KEY_KP_3 = sdl.KEY_KP_3 102 | KEY_KP_4 = sdl.KEY_KP_4 103 | KEY_KP_5 = sdl.KEY_KP_5 104 | KEY_KP_6 = sdl.KEY_KP_6 105 | KEY_KP_7 = sdl.KEY_KP_7 106 | KEY_KP_8 = sdl.KEY_KP_8 107 | KEY_KP_9 = sdl.KEY_KP_9 108 | KEY_KP_0 = sdl.KEY_KP_0 109 | KEY_KP_PERIOD = sdl.KEY_KP_PERIOD 110 | KEY_NONUSBACKSLASH = sdl.KEY_NONUSBACKSLASH 111 | KEY_APPLICATION = sdl.KEY_APPLICATION 112 | KEY_POWER = sdl.KEY_POWER 113 | KEY_KP_EQUALS = sdl.KEY_KP_EQUALS 114 | KEY_F13 = sdl.KEY_F13 115 | KEY_F14 = sdl.KEY_F14 116 | KEY_F15 = sdl.KEY_F15 117 | KEY_F16 = sdl.KEY_F16 118 | KEY_F17 = sdl.KEY_F17 119 | KEY_F18 = sdl.KEY_F18 120 | KEY_F19 = sdl.KEY_F19 121 | KEY_F20 = sdl.KEY_F20 122 | KEY_F21 = sdl.KEY_F21 123 | KEY_F22 = sdl.KEY_F22 124 | KEY_F23 = sdl.KEY_F23 125 | KEY_F24 = sdl.KEY_F24 126 | KEY_EXECUTE = sdl.KEY_EXECUTE 127 | KEY_HELP = sdl.KEY_HELP 128 | KEY_MENU = sdl.KEY_MENU 129 | KEY_SELECT = sdl.KEY_SELECT 130 | KEY_STOP = sdl.KEY_STOP 131 | KEY_AGAIN = sdl.KEY_AGAIN 132 | KEY_UNDO = sdl.KEY_UNDO 133 | KEY_CUT = sdl.KEY_CUT 134 | KEY_COPY = sdl.KEY_COPY 135 | KEY_PASTE = sdl.KEY_PASTE 136 | KEY_FIND = sdl.KEY_FIND 137 | KEY_MUTE = sdl.KEY_MUTE 138 | KEY_VOLUMEUP = sdl.KEY_VOLUMEUP 139 | KEY_VOLUMEDOWN = sdl.KEY_VOLUMEDOWN 140 | KEY_KP_COMMA = sdl.KEY_KP_COMMA 141 | KEY_KP_EQUALSAS400 = sdl.KEY_KP_EQUALSAS400 142 | KEY_INTERNATIONAL1 = sdl.KEY_INTERNATIONAL1 143 | KEY_INTERNATIONAL2 = sdl.KEY_INTERNATIONAL2 144 | KEY_INTERNATIONAL3 = sdl.KEY_INTERNATIONAL3 145 | KEY_INTERNATIONAL4 = sdl.KEY_INTERNATIONAL4 146 | KEY_INTERNATIONAL5 = sdl.KEY_INTERNATIONAL5 147 | KEY_INTERNATIONAL6 = sdl.KEY_INTERNATIONAL6 148 | KEY_INTERNATIONAL7 = sdl.KEY_INTERNATIONAL7 149 | KEY_INTERNATIONAL8 = sdl.KEY_INTERNATIONAL8 150 | KEY_INTERNATIONAL9 = sdl.KEY_INTERNATIONAL9 151 | KEY_LANG1 = sdl.KEY_LANG1 152 | KEY_LANG2 = sdl.KEY_LANG2 153 | KEY_LANG3 = sdl.KEY_LANG3 154 | KEY_LANG4 = sdl.KEY_LANG4 155 | KEY_LANG5 = sdl.KEY_LANG5 156 | KEY_LANG6 = sdl.KEY_LANG6 157 | KEY_LANG7 = sdl.KEY_LANG7 158 | KEY_LANG8 = sdl.KEY_LANG8 159 | KEY_LANG9 = sdl.KEY_LANG9 160 | KEY_ALTERASE = sdl.KEY_ALTERASE 161 | KEY_SYSREQ = sdl.KEY_SYSREQ 162 | KEY_CANCEL = sdl.KEY_CANCEL 163 | KEY_CLEAR = sdl.KEY_CLEAR 164 | KEY_PRIOR = sdl.KEY_PRIOR 165 | KEY_RETURN2 = sdl.KEY_RETURN2 166 | KEY_SEPARATOR = sdl.KEY_SEPARATOR 167 | KEY_OUT = sdl.KEY_OUT 168 | KEY_OPER = sdl.KEY_OPER 169 | KEY_CLEARAGAIN = sdl.KEY_CLEARAGAIN 170 | KEY_CRSEL = sdl.KEY_CRSEL 171 | KEY_EXSEL = sdl.KEY_EXSEL 172 | KEY_KP_00 = sdl.KEY_KP_00 173 | KEY_KP_000 = sdl.KEY_KP_000 174 | KEY_THOUSANDSSEPARATOR = sdl.KEY_THOUSANDSSEPARATOR 175 | KEY_DECIMALSEPARATOR = sdl.KEY_DECIMALSEPARATOR 176 | KEY_CURRENCYUNIT = sdl.KEY_CURRENCYUNIT 177 | KEY_CURRENCYSUBUNIT = sdl.KEY_CURRENCYSUBUNIT 178 | KEY_KP_LEFTPAREN = sdl.KEY_KP_LEFTPAREN 179 | KEY_KP_RIGHTPAREN = sdl.KEY_KP_RIGHTPAREN 180 | KEY_KP_LEFTBRACE = sdl.KEY_KP_LEFTBRACE 181 | KEY_KP_RIGHTBRACE = sdl.KEY_KP_RIGHTBRACE 182 | KEY_KP_TAB = sdl.KEY_KP_TAB 183 | KEY_KP_BACKSPACE = sdl.KEY_KP_BACKSPACE 184 | KEY_KP_A = sdl.KEY_KP_A 185 | KEY_KP_B = sdl.KEY_KP_B 186 | KEY_KP_C = sdl.KEY_KP_C 187 | KEY_KP_D = sdl.KEY_KP_D 188 | KEY_KP_E = sdl.KEY_KP_E 189 | KEY_KP_F = sdl.KEY_KP_F 190 | KEY_KP_XOR = sdl.KEY_KP_XOR 191 | KEY_KP_POWER = sdl.KEY_KP_POWER 192 | KEY_KP_PERCENT = sdl.KEY_KP_PERCENT 193 | KEY_KP_LESS = sdl.KEY_KP_LESS 194 | KEY_KP_GREATER = sdl.KEY_KP_GREATER 195 | KEY_KP_AMPERSAND = sdl.KEY_KP_AMPERSAND 196 | KEY_KP_DBLAMPERSAND = sdl.KEY_KP_DBLAMPERSAND 197 | KEY_KP_VERTICALBAR = sdl.KEY_KP_VERTICALBAR 198 | KEY_KP_DBLVERTICALBAR = sdl.KEY_KP_DBLVERTICALBAR 199 | KEY_KP_COLON = sdl.KEY_KP_COLON 200 | KEY_KP_HASH = sdl.KEY_KP_HASH 201 | KEY_KP_SPACE = sdl.KEY_KP_SPACE 202 | KEY_KP_AT = sdl.KEY_KP_AT 203 | KEY_KP_EXCLAM = sdl.KEY_KP_EXCLAM 204 | KEY_KP_MEMSTORE = sdl.KEY_KP_MEMSTORE 205 | KEY_KP_MEMRECALL = sdl.KEY_KP_MEMRECALL 206 | KEY_KP_MEMCLEAR = sdl.KEY_KP_MEMCLEAR 207 | KEY_KP_MEMADD = sdl.KEY_KP_MEMADD 208 | KEY_KP_MEMSUBTRACT = sdl.KEY_KP_MEMSUBTRACT 209 | KEY_KP_MEMMULTIPLY = sdl.KEY_KP_MEMMULTIPLY 210 | KEY_KP_MEMDIVIDE = sdl.KEY_KP_MEMDIVIDE 211 | KEY_KP_PLUSMINUS = sdl.KEY_KP_PLUSMINUS 212 | KEY_KP_CLEAR = sdl.KEY_KP_CLEAR 213 | KEY_KP_CLEARENTRY = sdl.KEY_KP_CLEARENTRY 214 | KEY_KP_BINARY = sdl.KEY_KP_BINARY 215 | KEY_KP_OCTAL = sdl.KEY_KP_OCTAL 216 | KEY_KP_DECIMAL = sdl.KEY_KP_DECIMAL 217 | KEY_KP_HEXADECIMAL = sdl.KEY_KP_HEXADECIMAL 218 | KEY_LCTRL = sdl.KEY_LCTRL 219 | KEY_LSHIFT = sdl.KEY_LSHIFT 220 | KEY_LALT = sdl.KEY_LALT 221 | KEY_LGUI = sdl.KEY_LGUI 222 | KEY_RCTRL = sdl.KEY_RCTRL 223 | KEY_RSHIFT = sdl.KEY_RSHIFT 224 | KEY_RALT = sdl.KEY_RALT 225 | KEY_RGUI = sdl.KEY_RGUI 226 | KEY_MODE = sdl.KEY_MODE 227 | KEY_AUDIONEXT = sdl.KEY_AUDIONEXT 228 | KEY_AUDIOPREV = sdl.KEY_AUDIOPREV 229 | KEY_AUDIOSTOP = sdl.KEY_AUDIOSTOP 230 | KEY_AUDIOPLAY = sdl.KEY_AUDIOPLAY 231 | KEY_AUDIOMUTE = sdl.KEY_AUDIOMUTE 232 | KEY_MEDIASELECT = sdl.KEY_MEDIASELECT 233 | KEY_WWW = sdl.KEY_WWW 234 | KEY_MAIL = sdl.KEY_MAIL 235 | KEY_CALCULATOR = sdl.KEY_CALCULATOR 236 | KEY_COMPUTER = sdl.KEY_COMPUTER 237 | KEY_AC_SEARCH = sdl.KEY_AC_SEARCH 238 | KEY_AC_HOME = sdl.KEY_AC_HOME 239 | KEY_AC_BACK = sdl.KEY_AC_BACK 240 | KEY_AC_FORWARD = sdl.KEY_AC_FORWARD 241 | KEY_AC_STOP = sdl.KEY_AC_STOP 242 | KEY_AC_REFRESH = sdl.KEY_AC_REFRESH 243 | KEY_AC_BOOKMARKS = sdl.KEY_AC_BOOKMARKS 244 | KEY_BRIGHTNESSDOWN = sdl.KEY_BRIGHTNESSDOWN 245 | KEY_BRIGHTNESSUP = sdl.KEY_BRIGHTNESSUP 246 | KEY_DISPLAYSWITCH = sdl.KEY_DISPLAYSWITCH 247 | KEY_KBDILLUMTOGGLE = sdl.KEY_KBDILLUMTOGGLE 248 | KEY_KBDILLUMDOWN = sdl.KEY_KBDILLUMDOWN 249 | KEY_KBDILLUMUP = sdl.KEY_KBDILLUMUP 250 | KEY_EJECT = sdl.KEY_EJECT 251 | KEY_SLEEP = sdl.KEY_SLEEP 252 | ) 253 | -------------------------------------------------------------------------------- /go2d/event.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import ( 4 | "sdl" 5 | ) 6 | 7 | func EventHandler(_event *sdl.SDLEvent) { 8 | switch _event.Evtype { 9 | case sdl.SDL_WINDOWEVENT: 10 | HandleWindowEvent(_event.Window()) 11 | 12 | case sdl.SDL_KEYDOWN, sdl.SDL_TEXTINPUT: 13 | HandleKeyboardEvent(_event.Keyboard()) 14 | 15 | case sdl.SDL_MOUSEBUTTONUP, sdl.SDL_MOUSEBUTTONDOWN: 16 | HandleMouseButtonEvent(_event.MouseButton()) 17 | 18 | case sdl.SDL_MOUSEMOTION: 19 | HandleMouseMotionEvent(_event.MouseMotion()) 20 | 21 | case sdl.SDL_MOUSEWHEEL: 22 | HandleMouseWheelEvent(_event.MouseWheel()) 23 | } 24 | } 25 | 26 | func HandleWindowEvent(_event *sdl.WindowEvent) { 27 | switch _event.Event { 28 | case sdl.SDL_WINDOWEVENT_CLOSE: 29 | g_running = false 30 | } 31 | } 32 | 33 | func HandleKeyboardEvent(_event *sdl.KeyboardEvent) { 34 | switch _event.Evtype { 35 | case sdl.SDL_KEYDOWN: 36 | if g_game.keydownFun != nil { 37 | g_game.keydownFun(int(_event.Keysym().Scancode)) 38 | } 39 | 40 | if g_game.guiManager != nil { 41 | g_game.guiManager.KeyDown(int(_event.Keysym().Scancode)) 42 | } 43 | 44 | case sdl.SDL_KEYUP: 45 | if g_game.keyupFun != nil { 46 | g_game.keyupFun(int(_event.Keysym().Scancode)) 47 | } 48 | 49 | if g_game.guiManager != nil { 50 | g_game.guiManager.KeyUp(int(_event.Keysym().Scancode)) 51 | } 52 | 53 | case sdl.SDL_TEXTINPUT: 54 | keysym := uint8(_event.State) 55 | if keysym != 0 && keysym > 31 { 56 | if g_game.textinputFun != nil { 57 | g_game.textinputFun(keysym) 58 | } 59 | } 60 | 61 | if g_game.guiManager != nil { 62 | g_game.guiManager.TextInput(keysym) 63 | } 64 | } 65 | } 66 | 67 | func HandleMouseButtonEvent(_event *sdl.MouseButtonEvent) { 68 | switch _event.Evtype { 69 | case sdl.SDL_MOUSEBUTTONUP: 70 | if g_game.mouseupFun != nil { 71 | g_game.mouseupFun(int16(_event.X), int16(_event.Y)) 72 | } 73 | 74 | if g_game.guiManager != nil { 75 | g_game.guiManager.MouseUp(int(_event.X), int(_event.Y)) 76 | } 77 | 78 | case sdl.SDL_MOUSEBUTTONDOWN: 79 | if g_game.mousedownFun != nil { 80 | g_game.mousedownFun(int16(_event.X), int16(_event.Y)) 81 | } 82 | 83 | if g_game.guiManager != nil { 84 | g_game.guiManager.MouseDown(int(_event.X), int(_event.Y)) 85 | } 86 | } 87 | } 88 | 89 | func HandleMouseMotionEvent(_event *sdl.MouseMotionEvent) { 90 | if g_game.mousemoveFun != nil { 91 | g_game.mousemoveFun(int16(_event.X), int16(_event.Y)) 92 | } 93 | 94 | if g_game.guiManager != nil { 95 | g_game.guiManager.MouseMove(int(_event.X), int(_event.Y)) 96 | } 97 | } 98 | 99 | func HandleMouseWheelEvent(_event *sdl.MouseWheelEvent) { 100 | direction := 0 101 | if 0-_event.Y < 0 { 102 | direction = sdl.SCROLL_UP 103 | } else if (0 - _event.Y) > 0 { 104 | direction = sdl.SCROLL_DOWN 105 | } 106 | 107 | if g_game.mousescrollFun != nil { 108 | g_game.mousescrollFun(direction) 109 | } 110 | 111 | if g_game.guiManager != nil { 112 | g_game.guiManager.MouseScroll(direction) 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /go2d/font.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import ( 4 | "fmt" 5 | "sdl" 6 | ) 7 | 8 | type Font struct { 9 | font *sdl.Font 10 | fontmap map[uint32]map[uint16]*Image 11 | color *sdl.Color 12 | size int 13 | style uint32 14 | alpha uint8 15 | } 16 | 17 | //Load font from file and specify font size (each font-size needs a seperate font instance) 18 | func NewFont(_file string, _size int) *Font { 19 | sdlfont := sdl.LoadFont(_file, _size) 20 | if sdlfont == nil { 21 | fmt.Printf("Go2D Error: Loading Font: %v", sdl.GetError()) 22 | } 23 | f := &Font{font: sdlfont, 24 | fontmap: make(map[uint32]map[uint16]*Image), 25 | color: &sdl.Color{255, 255, 255, 255}, 26 | alpha: 255, 27 | size: _size} 28 | addResource(f) 29 | f.build() 30 | return f 31 | } 32 | 33 | //Internal: release the font resource 34 | func (f *Font) release() { 35 | f.font.Release() 36 | } 37 | 38 | //Set the color (RGB values 0-255) 39 | func (f *Font) SetColor(_red uint8, _green uint8, _blue uint8) { 40 | f.color.R = _red 41 | f.color.G = _green 42 | f.color.B = _blue 43 | } 44 | 45 | //Set the opacity (0-255) 46 | func (f *Font) SetAlpha(_alpha uint8) { 47 | f.alpha = _alpha 48 | } 49 | 50 | //Set the style (bold, italic, underlined) 51 | func (f *Font) SetStyle(_bold bool, _italic bool, _underline bool) { 52 | var b, i, u uint32 = 0, 0, 0 53 | if _bold { 54 | b = 1 55 | } 56 | if _italic { 57 | i = 1 58 | } 59 | if _underline { 60 | u = 1 61 | } 62 | 63 | f.style = (b << 16) | (i << 8) | (u) 64 | 65 | _, present := f.fontmap[f.style] 66 | if !present { 67 | f.font.SetStyle(_bold, _italic, _underline) 68 | f.build() 69 | } 70 | } 71 | 72 | //Internal: build a map of all character textures 73 | func (f *Font) build() { 74 | f.fontmap[f.style] = make(map[uint16]*Image) 75 | for c := 32; c <= 127; c++ { 76 | surface := f.font.RenderText_Blended(fmt.Sprintf("%c", c), sdl.Color{255, 255, 255, 255}) 77 | img := newImageFromSurface(surface) 78 | 79 | f.fontmap[f.style][uint16(c)] = img 80 | } 81 | } 82 | 83 | //Draw a string on the given coordinates 84 | func (f *Font) DrawText(_text string, _x, _y int) { 85 | prev_char := -1 86 | for c := 0; c < len(_text); c++ { 87 | _, _, _, _, advance := f.font.GetMetrics(uint16(_text[c])) 88 | 89 | if prev_char != -1 { 90 | kerning := f.font.GetKerning(prev_char, int(_text[c])) 91 | _x += kerning 92 | 93 | prev_char = int(_text[c]) 94 | } 95 | 96 | img := f.fontmap[f.style][uint16(_text[c])] 97 | if img != nil { 98 | img.SetColorMod(f.color.R, f.color.G, f.color.B) 99 | img.SetAlphaMod(f.alpha) 100 | img.Draw(_x, _y) 101 | _x += advance 102 | } 103 | } 104 | } 105 | 106 | //Draw a string on the given coordinates, within a rect (text outside of the rect will be omitted) 107 | func (f *Font) DrawTextInRect(_text string, _x int, _y int, _rect *Rect) { 108 | prev_char := -1 109 | for c := 0; c < len(_text); c++ { 110 | _, _, _, _, advance := f.font.GetMetrics(uint16(_text[c])) 111 | 112 | if prev_char != -1 { 113 | kerning := f.font.GetKerning(prev_char, int(_text[c])) 114 | _x += kerning 115 | 116 | prev_char = int(_text[c]) 117 | } 118 | 119 | img := f.fontmap[f.style][uint16(_text[c])] 120 | if img != nil { 121 | img.SetColorMod(f.color.R, f.color.G, f.color.B) 122 | img.SetAlphaMod(f.alpha) 123 | img.DrawInRect(_x, _y, _rect) 124 | _x += advance 125 | } 126 | } 127 | } 128 | 129 | //Get the pixel width of the given string 130 | func (f *Font) GetStringWidth(_text string) int { 131 | w := 0 132 | prev_char := -1 133 | for c := 0; c < len(_text); c++ { 134 | _, _, _, _, advance := f.font.GetMetrics(uint16(_text[c])) 135 | 136 | if prev_char != -1 { 137 | kerning := f.font.GetKerning(prev_char, int(_text[c])) 138 | w += kerning 139 | 140 | prev_char = int(_text[c]) 141 | } 142 | 143 | w += advance 144 | } 145 | return w 146 | } 147 | 148 | //Get the pixel height of the font 149 | func (f *Font) GetStringHeight() int { 150 | return f.font.GetHeight() - 4 151 | } 152 | -------------------------------------------------------------------------------- /go2d/game.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import ( 4 | "fmt" 5 | "sdl" 6 | ) 7 | 8 | //Instance 9 | var g_game *Game 10 | var g_running bool 11 | 12 | //Basic game type 13 | 14 | type Game struct { 15 | initFun func() 16 | updateFun func(dt uint32) 17 | drawFun func() 18 | 19 | mouseupFun func(int16, int16) 20 | mousedownFun func(int16, int16) 21 | mousemoveFun func(int16, int16) 22 | mousescrollFun func(int) 23 | keydownFun func(int) 24 | keyupFun func(int) 25 | textinputFun func(uint8) 26 | 27 | title string 28 | width, height int 29 | d3d bool 30 | 31 | window *sdl.Window 32 | renderer *sdl.Renderer 33 | 34 | guiManager *GUIManager 35 | } 36 | 37 | //Create a new Game instance 38 | func NewGame(_title string) (game *Game) { 39 | game = &Game{} 40 | 41 | game.title = _title 42 | 43 | g_game = game 44 | return game 45 | } 46 | 47 | func (game *Game) InitGUI(x, y, width, height int, defaultFont *Font) *Window { 48 | game.guiManager = NewGUIManager(x, y, width, height, defaultFont) 49 | return game.guiManager.Root() 50 | } 51 | 52 | func (game *Game) SetInitFun(_init func()) { 53 | game.initFun = _init 54 | } 55 | 56 | func (game *Game) SetUpdateFun(_update func(dt uint32)) { 57 | game.updateFun = _update 58 | } 59 | 60 | func (game *Game) SetDrawFun(_draw func()) { 61 | game.drawFun = _draw 62 | } 63 | 64 | func (game *Game) SetMouseUpFun(_mouseup func(int16, int16)) { 65 | game.mouseupFun = _mouseup 66 | } 67 | 68 | func (game *Game) SetMouseDownFun(_mousedown func(int16, int16)) { 69 | game.mousedownFun = _mousedown 70 | } 71 | 72 | func (game *Game) SetMouseMoveFun(_mousemove func(int16, int16)) { 73 | game.mousemoveFun = _mousemove 74 | } 75 | 76 | func (game *Game) SetMouseScrollFun(_mousescroll func(int)) { 77 | game.mousescrollFun = _mousescroll 78 | } 79 | 80 | func (game *Game) SetKeyDownFun(_keydown func(int)) { 81 | game.keydownFun = _keydown 82 | } 83 | 84 | func (game *Game) SetKeyUpFun(_keyup func(int)) { 85 | game.keyupFun = _keyup 86 | } 87 | 88 | func (game *Game) SetTextInputFun(_textinput func(uint8)) { 89 | game.textinputFun = _textinput 90 | } 91 | 92 | //Internal initalization (executes when game starts) 93 | func (game *Game) initialize() { 94 | //Create the window 95 | var err string 96 | game.window, err = sdl.CreateWindow(game.title, game.width, game.height) 97 | if err != "" { 98 | panic(fmt.Sprintf("Go2D Error: Creating window: %s", err)) 99 | } 100 | 101 | //Create the renderer 102 | 103 | //Find our available renderers 104 | openglIndex := 0 105 | d3dIndex := -1 106 | numRenderers := sdl.GetNumRenderDrivers() 107 | for i := 0; i < numRenderers; i++ { 108 | rendererName := sdl.GetRenderDriverName(i) 109 | if rendererName == "opengl" { 110 | openglIndex = i 111 | } else if rendererName == "direct3d" { 112 | d3dIndex = i 113 | } 114 | } 115 | 116 | //Default renderer is OpenGL 117 | rendererIndex := openglIndex 118 | 119 | //If we want to use Direct3D and we found it, use it 120 | if game.d3d && d3dIndex != -1 { 121 | rendererIndex = d3dIndex 122 | } 123 | 124 | game.renderer, err = sdl.CreateRenderer(game.window, rendererIndex) 125 | if err != "" { 126 | panic(fmt.Sprintf("Go2D Error: Creating renderer: %s", err)) 127 | } 128 | 129 | //initialize font rendering 130 | sdl.InitTTF() 131 | 132 | //Call the user-defined init function 133 | if game.initFun != nil { 134 | game.initFun() 135 | } 136 | 137 | g_running = true 138 | } 139 | 140 | //Internal update function 141 | func (game *Game) update(dt uint32) { 142 | //Call user-defined update function 143 | if game.updateFun != nil { 144 | game.updateFun(dt) 145 | } 146 | } 147 | 148 | //Internal draw function 149 | func (game *Game) draw() { 150 | //Clear the screen 151 | sdl.RenderClear(game.renderer) 152 | 153 | //Call user-defined draw function 154 | if game.drawFun != nil { 155 | game.drawFun() 156 | } 157 | 158 | if game.guiManager != nil { 159 | game.guiManager.Draw() 160 | } 161 | 162 | //Render everything 163 | sdl.RenderPresent(game.renderer) 164 | } 165 | 166 | //Set window dimensions 167 | func (game *Game) SetDimensions(_width, _height int) { 168 | game.width = _width 169 | game.height = _height 170 | } 171 | 172 | //Try to use D3D or not 173 | func (game *Game) SetD3D(_d3d bool) { 174 | game.d3d = _d3d 175 | } 176 | 177 | //Game loop 178 | func (game *Game) Run() { 179 | defer game.Exit() 180 | 181 | if game.initFun == nil { 182 | fmt.Println("Go2D Warning: No init function set!") 183 | } 184 | 185 | if game.updateFun == nil { 186 | fmt.Println("Go2D Warning: No update function set!") 187 | } 188 | 189 | if game.drawFun == nil { 190 | fmt.Println("Go2D Warning: No draw function set!") 191 | } 192 | 193 | //Initialize the game 194 | game.initialize() 195 | 196 | var dt, old_t, now_t uint32 = 0, 0, 0 197 | 198 | for g_running { 199 | //Check for events and handle them 200 | for { 201 | event, present := sdl.PollEvent() 202 | if present { 203 | EventHandler(event) 204 | } else { 205 | break 206 | } 207 | } 208 | 209 | //Calculate time delta 210 | now_t = sdl.GetTicks() 211 | dt = now_t - old_t 212 | old_t = now_t 213 | 214 | //Update 215 | game.update(dt) 216 | 217 | //Draw 218 | game.draw() 219 | 220 | //Give the CPU some time to do other stuff 221 | sdl.Delay(1) 222 | } 223 | } 224 | 225 | //Release all resources 226 | func (game *Game) Exit() { 227 | freeResources() 228 | 229 | //Destroy the renderer 230 | game.renderer.Release() 231 | 232 | //Destroy the window 233 | sdl.DestroyWindow(game.window) 234 | 235 | //Quit SDL_ttf 236 | sdl.QuitTTF() 237 | 238 | //Quit SDL 239 | sdl.Quit() 240 | } 241 | -------------------------------------------------------------------------------- /go2d/gui/button.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import "sdl" 4 | 5 | type Button struct { 6 | Element 7 | 8 | //Properties 9 | BackgroundColor 10 | ElementImage 11 | TextElement 12 | 13 | //Listeners 14 | OnClickListener 15 | 16 | //Members 17 | caption string 18 | mouseDown bool 19 | hover bool 20 | } 21 | 22 | func NewButton(x, y, width, height int, caption string) *Button { 23 | button := &Button{} 24 | button.Init(x, y, width, height) 25 | button.caption = caption 26 | button.SetFont(g_game.guiManager.defaultFont) 27 | button.fontColor = &sdl.Color{uint8(255), uint8(255), uint8(255), uint8(255)} 28 | return button 29 | } 30 | 31 | func (b *Button) Caption() string { 32 | return b.caption 33 | } 34 | 35 | func (b *Button) SetCaption(caption string) { 36 | b.caption = caption 37 | } 38 | 39 | func (b *Button) Draw(drawArea *Rect) { 40 | realRect := NewRect(b.Rect().X+drawArea.X, b.Rect().Y+drawArea.Y, b.Rect().Width, b.Rect().Height) 41 | inRect := drawArea.Intersection(realRect) 42 | 43 | if b.backgroundColor != nil { 44 | DrawFillRect(inRect, b.backgroundColor.R, b.backgroundColor.G, b.backgroundColor.B, 255) 45 | } 46 | 47 | var drawable *Image 48 | switch { 49 | case b.mouseDown && b.mouseDownImage != nil: 50 | drawable = b.mouseDownImage 51 | 52 | case b.hover && b.hoverImage != nil: 53 | drawable = b.hoverImage 54 | 55 | default: 56 | drawable = b.image 57 | } 58 | if drawable != nil { 59 | drawable.DrawRectInRect(b.Rect(), drawArea) 60 | } 61 | 62 | if b.caption != "" && b.font != nil { 63 | captionX := b.Rect().X+((b.Rect().Width/2)-(b.font.GetStringWidth(b.caption)/2)); 64 | captionY := b.Rect().Y+((b.Rect().Height/2)-(b.font.GetStringHeight()/2)); 65 | b.font.SetStyle(b.bold, b.italic, b.underlined) 66 | b.font.SetColor(b.fontColor.R, b.fontColor.G, b.fontColor.B) 67 | b.font.DrawTextInRect(b.caption, drawArea.X + captionX, drawArea.Y + captionY, inRect) 68 | } 69 | } 70 | 71 | func (b *Button) MouseMove(x, y int) { 72 | if b.Rect().Contains(x, y) { 73 | b.hover = true 74 | } else { 75 | b.hover = false 76 | } 77 | } 78 | 79 | func (b *Button) MouseDown(x, y int) { 80 | if b.Rect().Contains(x, y) { 81 | b.mouseDown = true 82 | } 83 | } 84 | 85 | func (b *Button) MouseUp(x, y int) { 86 | if b.Rect().Contains(x, y) { 87 | if b.mouseDown && b.onClick != nil { 88 | b.onClick(x, y) 89 | } 90 | } 91 | b.mouseDown = false 92 | } 93 | -------------------------------------------------------------------------------- /go2d/gui/container.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | type IContainer interface { 4 | Children() []IElement 5 | FillFocusList(elements *[]IElement) 6 | } 7 | 8 | type Container struct { 9 | Element 10 | children []IElement 11 | } 12 | 13 | func (c *Container) Init(x, y, width, height int) { 14 | c.Element.Init(x, y, width, height) 15 | c.children = make([]IElement, 0) 16 | } 17 | 18 | func (c *Container) FillFocusList(elements *[]IElement) { 19 | for _, child := range c.children { 20 | switch childType := child.(type) { 21 | case IContainer: 22 | childType.FillFocusList(elements) 23 | 24 | default: 25 | if child.Focusable() { 26 | *elements = append(*elements, child) 27 | } 28 | } 29 | } 30 | } 31 | 32 | func (c *Container) Children() []IElement { 33 | return c.children 34 | } 35 | 36 | func (c *Container) AddChild(element IElement) { 37 | element.SetParent(c) 38 | c.children = append(c.children, element) 39 | } 40 | 41 | func (c *Container) RemoveChild(element IElement) { 42 | for index, child := range c.children { 43 | if child == element { 44 | h := c.children[0:index] 45 | l := c.children[index+1:] 46 | c.children = append(h, l...) 47 | } 48 | } 49 | } 50 | 51 | func (c *Container) Draw(drawArea *Rect) { 52 | if c.InDrawArea(drawArea) { 53 | childDrawArea := NewRectFrom(drawArea) 54 | childDrawArea.X += c.Rect().X 55 | childDrawArea.Y += c.Rect().Y 56 | childDrawArea.Width = c.Rect().Width 57 | childDrawArea.Height = c.Rect().Height 58 | 59 | for _, child := range c.Children() { 60 | if child.Visible() && child.InDrawArea(drawArea) { 61 | child.Draw(childDrawArea) 62 | } 63 | } 64 | } 65 | } 66 | 67 | func (c *Container) MouseDown(x, y int) { 68 | for _, child := range c.Children() { 69 | if child.Visible() { 70 | child.MouseDown(x - c.Rect().X, y - c.Rect().Y) 71 | } 72 | } 73 | } 74 | 75 | func (c *Container) MouseUp(x, y int) { 76 | for _, child := range c.Children() { 77 | if child.Visible() { 78 | child.MouseUp(x - c.Rect().X, y - c.Rect().Y) 79 | } 80 | } 81 | } 82 | 83 | func (c *Container) MouseMove(x, y int) { 84 | for _, child := range c.Children() { 85 | if child.Visible() { 86 | child.MouseMove(x - c.Rect().X, y - c.Rect().Y) 87 | } 88 | } 89 | } 90 | 91 | func (c *Container) MouseScroll(direction int) { 92 | for _, child := range c.Children() { 93 | if child.Visible() { 94 | child.MouseScroll(direction) 95 | } 96 | } 97 | } 98 | 99 | func (c *Container) KeyDown(button int) { 100 | for _, child := range c.Children() { 101 | if child.Visible() { 102 | child.KeyDown(button) 103 | } 104 | } 105 | } 106 | 107 | func (c *Container) KeyUp(button int) { 108 | for _, child := range c.Children() { 109 | if child.Visible() { 110 | child.KeyUp(button) 111 | } 112 | } 113 | } 114 | 115 | func (c *Container) TextInput(character uint8) { 116 | for _, child := range c.Children() { 117 | if child.Visible() { 118 | child.TextInput(character) 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /go2d/gui/element.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | type IElement interface { 4 | Draw(drawArea *Rect) 5 | MouseDown(x, y int) 6 | MouseUp(x, y int) 7 | MouseMove(x, y int) 8 | MouseScroll(direction int) 9 | KeyDown(button int) 10 | KeyUp(button int) 11 | TextInput(character uint8) 12 | Rect() *Rect 13 | Visible() bool 14 | Parent() IElement 15 | SetParent(element IElement) 16 | Focus() bool 17 | SetFocus(focus bool) 18 | Focusable() bool 19 | Window() *Window 20 | InDrawArea(drawArea *Rect) bool 21 | } 22 | 23 | type Element struct { 24 | rect *Rect 25 | visible bool 26 | parent IElement 27 | focus bool 28 | focusable bool 29 | } 30 | 31 | func (e *Element) Init(x, y, width, height int) { 32 | e.rect = NewRect(x, y, width, height) 33 | e.visible = true 34 | } 35 | 36 | func (e *Element) Draw(drawArea *Rect) { 37 | } 38 | 39 | func (e *Element) MouseDown(x, y int) { 40 | } 41 | 42 | func (e *Element) MouseUp(x, y int) { 43 | } 44 | 45 | func (e *Element) MouseMove(x, y int) { 46 | } 47 | 48 | func (e *Element) MouseScroll(direction int) { 49 | } 50 | 51 | func (e *Element) KeyDown(button int) { 52 | } 53 | 54 | func (e *Element) KeyUp(button int) { 55 | } 56 | 57 | func (e *Element) TextInput(character uint8) { 58 | } 59 | 60 | func (e *Element) Visible() bool { 61 | return e.visible 62 | } 63 | 64 | func (e *Element) Rect() *Rect { 65 | return e.rect 66 | } 67 | 68 | func (e *Element) Parent() IElement { 69 | return e.parent 70 | } 71 | 72 | func (e *Element) SetParent(element IElement) { 73 | e.parent = element 74 | } 75 | 76 | func (e *Element) Focus() bool { 77 | return e.focus 78 | } 79 | 80 | func (e *Element) SetFocus(focus bool) { 81 | e.focus = focus 82 | } 83 | 84 | func (e *Element) Focusable() bool { 85 | return e.focusable 86 | } 87 | 88 | func (e *Element) Window() *Window { 89 | if e.Parent() != nil { 90 | if window, is_window := e.Parent().(*Window); is_window { 91 | return window 92 | } 93 | return e.Parent().Window() 94 | } 95 | return nil 96 | } 97 | 98 | func (e *Element) InDrawArea(drawArea *Rect) bool { 99 | if e.Rect() == nil || drawArea == nil { 100 | return false 101 | } 102 | 103 | if drawArea.Contains(e.Rect().X, e.Rect().Y) { 104 | return true 105 | } 106 | 107 | if drawArea.Contains(e.Rect().X+e.Rect().Width, e.Rect().Y) { 108 | return true 109 | } 110 | 111 | if drawArea.Contains(e.Rect().X, e.Rect().Y+e.Rect().Height) { 112 | return true 113 | } 114 | 115 | if drawArea.Contains(e.Rect().X+e.Rect().Width, e.Rect().Y+e.Rect().Height) { 116 | return true 117 | } 118 | 119 | return false 120 | } -------------------------------------------------------------------------------- /go2d/gui/element_properties.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import "sdl" 4 | 5 | type BackgroundColor struct { 6 | backgroundColor *sdl.Color 7 | } 8 | 9 | func (b *BackgroundColor) BackgroundColor() *sdl.Color { 10 | return b.backgroundColor 11 | } 12 | 13 | func (b *BackgroundColor) SetBackgroundColor(red, green, blue int) { 14 | if b.backgroundColor == nil { 15 | b.backgroundColor = &sdl.Color{uint8(red), uint8(green), uint8(blue), uint8(255)} 16 | } else { 17 | b.backgroundColor.R = uint8(red) 18 | b.backgroundColor.G = uint8(green) 19 | b.backgroundColor.B = uint8(blue) 20 | } 21 | } 22 | 23 | type BorderColor struct { 24 | borderColor *sdl.Color 25 | } 26 | 27 | func (b *BorderColor) BorderColor() *sdl.Color { 28 | return b.borderColor 29 | } 30 | 31 | func (b *BorderColor) SetBorderColor(red, green, blue int) { 32 | if b.borderColor == nil { 33 | b.borderColor = &sdl.Color{uint8(red), uint8(green), uint8(blue), uint8(255)} 34 | } else { 35 | b.borderColor.R = uint8(red) 36 | b.borderColor.G = uint8(green) 37 | b.borderColor.B = uint8(blue) 38 | } 39 | } 40 | 41 | type ElementImage struct { 42 | image *Image 43 | hoverImage *Image 44 | mouseDownImage *Image 45 | } 46 | 47 | func (e *ElementImage) Image() *Image { 48 | return e.image 49 | } 50 | 51 | func (e *ElementImage) SetImage(image *Image) { 52 | e.image = image 53 | } 54 | 55 | func (e *ElementImage) HoverImage() *Image { 56 | return e.hoverImage 57 | } 58 | 59 | func (e *ElementImage) SetHoverImage(image *Image) { 60 | e.hoverImage = image 61 | } 62 | 63 | func (e *ElementImage) MouseDownImage() *Image { 64 | return e.mouseDownImage 65 | } 66 | 67 | func (e *ElementImage) SetMouseDownImage(image *Image) { 68 | e.mouseDownImage = image 69 | } 70 | 71 | type Value struct { 72 | value int 73 | } 74 | 75 | func (v *Value) Value() int { 76 | return v.value 77 | } 78 | 79 | func (v *Value) SetValue(value int) { 80 | v.value = value 81 | } -------------------------------------------------------------------------------- /go2d/gui/label.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import "sdl" 4 | 5 | type Label struct { 6 | Element 7 | TextElement 8 | 9 | caption string 10 | } 11 | 12 | func NewLabel(x, y int, caption string) *Label { 13 | label := &Label{} 14 | 15 | label.Init(x, y, 0, 0) 16 | 17 | label.caption = caption 18 | 19 | label.SetFont(g_game.guiManager.defaultFont) 20 | label.fontColor = &sdl.Color{uint8(255), uint8(255), uint8(255), uint8(255)} 21 | 22 | return label 23 | } 24 | 25 | func (l *Label) SetCaption(caption string) { 26 | l.caption = caption 27 | } 28 | 29 | func (l *Label) Caption() string { 30 | return l.caption 31 | } 32 | 33 | func (l *Label) SetFont(font *Font) { 34 | l.font = font 35 | width, height := 0, 0 36 | if l.font != nil { 37 | width = l.font.GetStringWidth(l.caption) 38 | height = l.font.GetStringHeight()+2 39 | } 40 | l.Rect().Width = width 41 | l.Rect().Height = height 42 | } 43 | 44 | func (l *Label) Draw(drawArea *Rect) { 45 | realRect := NewRect(l.Rect().X+drawArea.X, l.Rect().Y+drawArea.Y, l.Rect().Width, l.Rect().Height) 46 | inRect := drawArea.Intersection(realRect) 47 | 48 | if l.font != nil { 49 | l.font.SetStyle(l.bold, l.italic, l.underlined) 50 | l.font.SetColor(l.fontColor.R, l.fontColor.G, l.fontColor.B) 51 | l.font.DrawTextInRect(l.caption, drawArea.X + l.Rect().X, drawArea.Y + l.Rect().Y, inRect) 52 | } 53 | } -------------------------------------------------------------------------------- /go2d/gui/listener.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | type OnClickListener struct { 4 | onClick func(x, y int) 5 | } 6 | 7 | func (o *OnClickListener) SetOnClickListener(onClick func(int, int)) { 8 | o.onClick = onClick 9 | } 10 | 11 | type OnKeyDownListener struct { 12 | onKeyDown func(button int) 13 | } 14 | 15 | func (o *OnKeyDownListener) SetOnKeyDownListener(onKeyDown func(int)) { 16 | o.onKeyDown = onKeyDown 17 | } 18 | 19 | type OnScrollChangeListener struct { 20 | onScrollChange func(scrolledX, scrolledY int) 21 | } 22 | 23 | func (o *OnScrollChangeListener) SetOnScrollChangeListener(onScrollChange func(scrolledX, scrolledY int)) { 24 | o.onScrollChange = onScrollChange 25 | } 26 | 27 | type OnValueChangeListener struct { 28 | onValueChange func(value int) 29 | } 30 | 31 | func (o *OnValueChangeListener) SetOnValueChangeListener(onValueChange func(value int)) { 32 | o.onValueChange = onValueChange 33 | } -------------------------------------------------------------------------------- /go2d/gui/manager.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | type GUIManager struct { 4 | root *Window 5 | defaultFont *Font 6 | } 7 | 8 | func NewGUIManager(x, y, width, height int, defaultFont *Font) *GUIManager { 9 | manager := &GUIManager{} 10 | manager.root = NewWindow(x, y, width, height) 11 | manager.defaultFont = defaultFont 12 | return manager 13 | } 14 | 15 | func (m *GUIManager) Root() *Window { 16 | return m.root 17 | } 18 | 19 | func (m *GUIManager) DefaultFont() *Font { 20 | return m.defaultFont 21 | } 22 | 23 | func (m *GUIManager) Draw() { 24 | if m.root != nil { 25 | m.root.Draw(m.root.Rect()) 26 | } 27 | } 28 | 29 | func (m *GUIManager) MouseDown(x, y int) { 30 | if m.root != nil { 31 | m.root.MouseDown(x, y) 32 | } 33 | } 34 | 35 | func (m *GUIManager) MouseUp(x, y int) { 36 | if m.root != nil { 37 | m.root.MouseUp(x, y) 38 | } 39 | } 40 | 41 | func (m *GUIManager) MouseMove(x, y int) { 42 | if m.root != nil { 43 | m.root.MouseMove(x, y) 44 | } 45 | } 46 | func (m *GUIManager) MouseScroll(direction int) { 47 | if m.root != nil { 48 | m.root.MouseScroll(direction) 49 | } 50 | } 51 | 52 | func (m *GUIManager) KeyDown(button int) { 53 | if m.root != nil { 54 | m.root.KeyDown(button) 55 | } 56 | } 57 | 58 | func (m *GUIManager) KeyUp(button int) { 59 | if m.root != nil { 60 | m.root.KeyUp(button) 61 | } 62 | } 63 | 64 | func (m *GUIManager) TextInput(character uint8) { 65 | if m.root != nil { 66 | m.root.TextInput(character) 67 | } 68 | } -------------------------------------------------------------------------------- /go2d/gui/panel.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | type Panel struct { 4 | Container 5 | BackgroundColor 6 | } 7 | 8 | func NewPanel(x, y, width, height int) *Panel { 9 | panel := &Panel{} 10 | panel.Init(x, y, width, height) 11 | return panel 12 | } 13 | 14 | func (p *Panel) Draw(drawArea *Rect) { 15 | if p.backgroundColor != nil { 16 | realRect := NewRect(p.Rect().X+drawArea.X, p.Rect().Y+drawArea.Y, p.Rect().Width, p.Rect().Height) 17 | inRect := drawArea.Intersection(realRect) 18 | 19 | DrawFillRect(inRect, p.backgroundColor.R, p.backgroundColor.G, p.backgroundColor.B, 255) 20 | } 21 | 22 | p.Container.Draw(drawArea) 23 | } -------------------------------------------------------------------------------- /go2d/gui/scrollbar.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | const ( 4 | SCROLLBAR_VERTICAL = iota 5 | SCROLLBAR_HORIZONTAL 6 | ) 7 | 8 | type Scrollbar struct { 9 | Container 10 | 11 | //Properties 12 | Value 13 | 14 | //Listeners 15 | OnValueChangeListener 16 | 17 | //Members 18 | orientation int 19 | pnlBackground *Panel 20 | btnLeftTop, btnRightDown *Button 21 | scbScroller *ScrollButton 22 | minValue, maxValue int 23 | } 24 | 25 | func NewScrollbar(x, y, width, height, orientation int) *Scrollbar { 26 | scrollbar := &Scrollbar{} 27 | scrollbar.Init(x, y, width, height) 28 | scrollbar.orientation = orientation 29 | 30 | scrollbar.value = 0 31 | scrollbar.minValue = 0 32 | scrollbar.maxValue = 100 33 | 34 | scrollbar.pnlBackground = NewPanel(0, 0, width, height) 35 | scrollbar.pnlBackground.SetBackgroundColor(80, 80, 80) 36 | scrollbar.AddChild(scrollbar.pnlBackground) 37 | 38 | if orientation == SCROLLBAR_VERTICAL { 39 | scrollbar.btnLeftTop = NewButton(0, 0, width, width, "") 40 | scrollbar.btnRightDown = NewButton(0, height-width, width, width, "") 41 | scrollbar.scbScroller = NewScrollButton(0, width, width, width, NewRect(0, width, width, height-(2*width))) 42 | } else { 43 | scrollbar.btnLeftTop = NewButton(0, 0, height, height, "") 44 | scrollbar.btnRightDown = NewButton(width-height, 0, height, height, "") 45 | scrollbar.scbScroller = NewScrollButton(height, 0, height, height, NewRect(height, 0, height, width-(2*height))) 46 | } 47 | scrollbar.btnLeftTop.SetBackgroundColor(120,120,120) 48 | scrollbar.btnRightDown.SetBackgroundColor(120,120,120) 49 | scrollbar.scbScroller.SetBackgroundColor(100,100,100) 50 | 51 | scrollbar.AddChild(scrollbar.btnLeftTop) 52 | scrollbar.AddChild(scrollbar.btnRightDown) 53 | scrollbar.AddChild(scrollbar.scbScroller) 54 | 55 | scrollbar.scbScroller.onScrollChange = func(scrolledX, scrolledY int) { 56 | scrollbar.ScrollButtonChanged(scrolledX, scrolledY) 57 | } 58 | 59 | scrollbar.btnLeftTop.SetOnClickListener(func(x, y int) { 60 | if scrollbar.value-1 >= scrollbar.minValue { 61 | scrollbar.value-- 62 | scrollbar.UpdateScrollerPos() 63 | 64 | if scrollbar.onValueChange != nil { 65 | scrollbar.onValueChange(scrollbar.value) 66 | } 67 | } 68 | }) 69 | 70 | scrollbar.btnRightDown.SetOnClickListener(func(x, y int) { 71 | if scrollbar.value+1 <= scrollbar.maxValue { 72 | scrollbar.value++ 73 | scrollbar.UpdateScrollerPos() 74 | 75 | if scrollbar.onValueChange != nil { 76 | scrollbar.onValueChange(scrollbar.value) 77 | } 78 | } 79 | }) 80 | 81 | return scrollbar 82 | } 83 | 84 | func (s *Scrollbar) ScrollButtonChanged(scrolledX, scrolledY int) { 85 | s.value = s.minValue + int((float32(scrolledY) / float32(s.ScrollAreaSize())) * float32(s.maxValue)) 86 | 87 | if s.onValueChange != nil { 88 | s.onValueChange(s.value) 89 | } 90 | } 91 | 92 | func (s *Scrollbar) ButtonLeftTop() *Button { 93 | return s.btnLeftTop 94 | } 95 | 96 | func (s *Scrollbar) ButtonRightDown() *Button { 97 | return s.btnRightDown 98 | } 99 | 100 | func (s *Scrollbar) Scroller() *ScrollButton { 101 | return s.scbScroller 102 | } 103 | 104 | func (s *Scrollbar) MinValue() int { 105 | return s.minValue 106 | } 107 | 108 | func (s *Scrollbar) SetMinValue(minValue int) { 109 | s.minValue = minValue 110 | } 111 | 112 | func (s *Scrollbar) MaxValue() int { 113 | return s.maxValue 114 | } 115 | 116 | func (s *Scrollbar) SetMaxValue(maxValue int) { 117 | s.maxValue = maxValue 118 | } 119 | 120 | func (s *Scrollbar) ScrollAreaSize() int { 121 | if s.orientation == SCROLLBAR_VERTICAL { 122 | return s.Rect().Height-s.btnLeftTop.Rect().Height-s.btnRightDown.Rect().Height-s.scbScroller.Rect().Height; 123 | } 124 | return s.Rect().Width-s.btnLeftTop.Rect().Width-s.btnRightDown.Rect().Width-s.scbScroller.Rect().Width; 125 | } 126 | 127 | func (s *Scrollbar) UpdateScrollerPos() { 128 | delta := s.maxValue - s.minValue 129 | size := 0 130 | if delta != 0 { 131 | size = int(float32(s.value - s.minValue) * float32(s.ScrollAreaSize()) / float32(delta)) 132 | } 133 | 134 | if s.orientation == SCROLLBAR_VERTICAL { 135 | size += s.btnLeftTop.Rect().Y + s.btnLeftTop.Rect().Height 136 | s.scbScroller.Rect().Y = size 137 | } else { 138 | size += s.btnRightDown.Rect().X + s.btnRightDown.Rect().Width 139 | s.scbScroller.Rect().X = size 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /go2d/gui/scrollbutton.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | type ScrollButton struct { 4 | Button 5 | 6 | OnScrollChangeListener 7 | 8 | boundaries *Rect 9 | startX, startY int 10 | mouseDownX, mouseDownY int 11 | scrolling bool 12 | } 13 | 14 | func NewScrollButton(x, y, width, height int, boundaries *Rect) *ScrollButton { 15 | scrollButton := &ScrollButton{} 16 | scrollButton.Init(x, y, width, height) 17 | scrollButton.boundaries = boundaries 18 | return scrollButton 19 | } 20 | 21 | func (s *ScrollButton) Boundaries() *Rect { 22 | return s.boundaries 23 | } 24 | 25 | func (s *ScrollButton) SetBoundaries(boundaries *Rect) { 26 | s.boundaries = boundaries 27 | } 28 | 29 | func (s *ScrollButton) MouseDown(x, y int) { 30 | s.startX = s.Rect().X 31 | s.startY = s.Rect().Y 32 | 33 | s.mouseDownX = x 34 | s.mouseDownY = y 35 | 36 | s.Button.MouseDown(x, y) 37 | } 38 | 39 | func (s *ScrollButton) UpdateScrollChangeListener() { 40 | if s.onScrollChange != nil { 41 | s.onScrollChange(s.ScrolledX(), s.ScrolledY()) 42 | } 43 | } 44 | 45 | func (s *ScrollButton) MouseUp(x, y int) { 46 | if !s.scrolling && !s.mouseDown && s.boundaries != nil && s.boundaries.Contains(x, y) { 47 | newX := (s.boundaries.X + (x - s.boundaries.X)) - (s.Rect().Width/2) 48 | if newX >= s.boundaries.X && newX+s.Rect().Width <= s.boundaries.X+s.boundaries.Width { 49 | s.Rect().X = newX 50 | } 51 | 52 | newY := (s.boundaries.Y + (y - s.boundaries.Y)) - (s.Rect().Height/2) 53 | if newY >= s.boundaries.Y && newY+s.Rect().Height <= s.boundaries.Y+s.boundaries.Height { 54 | s.Rect().Y = newY 55 | } 56 | 57 | s.UpdateScrollChangeListener() 58 | } 59 | s.scrolling = false 60 | s.Button.MouseUp(x, y) 61 | } 62 | 63 | func (s *ScrollButton) MouseMove(x, y int) { 64 | if s.boundaries != nil && s.mouseDown { 65 | s.scrolling = true 66 | 67 | newX := s.startX + (x - s.mouseDownX) 68 | if newX >= s.boundaries.X && newX+s.Rect().Width <= s.boundaries.X+s.boundaries.Width { 69 | s.Rect().X = newX 70 | } else if newX < s.boundaries.X { 71 | s.Rect().X = s.boundaries.X 72 | } else if newX > s.boundaries.X+s.boundaries.Width { 73 | s.Rect().X = s.boundaries.Width - s.Rect().Width 74 | } 75 | 76 | newY := s.startY + (y - s.mouseDownY) 77 | if newY >= s.boundaries.Y && newY+s.Rect().Height <= s.boundaries.Y+s.boundaries.Height { 78 | s.Rect().Y = newY 79 | } else if newY < s.boundaries.Y { 80 | s.Rect().Y = s.boundaries.Y 81 | } else if newY > s.boundaries.Height { 82 | s.Rect().Y = s.boundaries.Height 83 | } 84 | 85 | s.UpdateScrollChangeListener() 86 | } 87 | } 88 | 89 | func (s *ScrollButton) ScrolledX() int { 90 | return s.Rect().X - s.boundaries.X 91 | } 92 | 93 | func (s *ScrollButton) ScrolledY() int { 94 | return s.Rect().Y - s.boundaries.Y 95 | } -------------------------------------------------------------------------------- /go2d/gui/textelement.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import "sdl" 4 | 5 | type TextElement struct { 6 | font *Font 7 | fontColor *sdl.Color 8 | bold, italic, underlined bool 9 | } 10 | 11 | func (t *TextElement) SetFont(font *Font) { 12 | t.font = font 13 | } 14 | 15 | func (t *TextElement) Font() *Font { 16 | return t.font 17 | } 18 | 19 | func (t *TextElement) SetFontColor(red, green, blue int) { 20 | t.fontColor.R = uint8(red) 21 | t.fontColor.G = uint8(green) 22 | t.fontColor.B = uint8(blue) 23 | } 24 | 25 | func (t *TextElement) FontColor() *sdl.Color { 26 | return t.fontColor 27 | } 28 | 29 | func (t *TextElement) SetFontStyle(bold, italic, underlined bool) { 30 | t.bold = bold 31 | t.italic = italic 32 | t.underlined = underlined 33 | } 34 | 35 | func (t *TextElement) Bold() bool { 36 | return t.bold 37 | } 38 | 39 | func (t *TextElement) Italic() bool { 40 | return t.italic 41 | } 42 | 43 | func (t *TextElement) Underlined() bool { 44 | return t.underlined 45 | } -------------------------------------------------------------------------------- /go2d/gui/textfield.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import "sdl" 4 | 5 | const ( 6 | CARET_TIME = 500 7 | ) 8 | 9 | type TextField struct { 10 | Element 11 | 12 | //Properties 13 | BackgroundColor 14 | BorderColor 15 | ElementImage 16 | TextElement 17 | 18 | //Listeners 19 | OnKeyDownListener 20 | 21 | //Members 22 | text string 23 | readonly bool 24 | password bool 25 | caret bool 26 | caretLast uint32 27 | } 28 | 29 | func NewTextField(x, y, width, height int) *TextField { 30 | textfield := &TextField{} 31 | textfield.Init(x, y, width, height) 32 | textfield.focusable = true 33 | textfield.SetFont(g_game.guiManager.defaultFont) 34 | textfield.fontColor = &sdl.Color{uint8(255), uint8(255), uint8(255), uint8(255)} 35 | textfield.caretLast = sdl.GetTicks() 36 | return textfield 37 | } 38 | 39 | func (t *TextField) Text() string { 40 | return t.text 41 | } 42 | 43 | func (t *TextField) SetText(text string) { 44 | t.text = text 45 | } 46 | 47 | func (t *TextField) ReadOnly() bool { 48 | return t.readonly 49 | } 50 | 51 | func (t *TextField) SetReadOnly(readonly bool) { 52 | t.readonly = readonly 53 | } 54 | 55 | func (t *TextField) Password() bool { 56 | return t.password 57 | } 58 | 59 | func (t *TextField) SetPassword(password bool) { 60 | t.password = password 61 | } 62 | 63 | func (t *TextField) KeyDown(button int) { 64 | if !t.readonly && t.focus { 65 | if button == KEY_BACKSPACE { 66 | if len(t.text) > 0 { 67 | textlength := len(t.text) 68 | t.text = t.text[0 : textlength-1] 69 | } 70 | } 71 | } 72 | 73 | if t.onKeyDown != nil { 74 | t.onKeyDown(button) 75 | } 76 | } 77 | 78 | func (t *TextField) TextInput(char uint8) { 79 | if !t.readonly && t.focus { 80 | if char != 0 && char > 31 { 81 | t.text += string(char) 82 | } 83 | } 84 | } 85 | 86 | func (t *TextField) Draw(drawArea *Rect) { 87 | realRect := NewRect(t.Rect().X+drawArea.X, t.Rect().Y+drawArea.Y, t.Rect().Width, t.Rect().Height) 88 | inRect := drawArea.Intersection(realRect) 89 | 90 | if t.backgroundColor != nil { 91 | DrawFillRect(inRect, t.backgroundColor.R, t.backgroundColor.G, t.backgroundColor.B, 255) 92 | } 93 | 94 | if t.borderColor != nil { 95 | DrawRect(inRect, t.borderColor.R, t.borderColor.G, t.borderColor.B, 255) 96 | } 97 | 98 | if t.image != nil { 99 | t.image.DrawRectInRect(t.Rect(), drawArea) 100 | } 101 | 102 | caretX := 0 103 | textX := t.Rect().X+(t.font.GetStringWidth(" ")); 104 | textY := t.Rect().Y+((t.Rect().Height/2)-(t.font.GetStringHeight()/2)); 105 | 106 | if t.text != "" && t.font != nil { 107 | var drawText string 108 | if t.password { 109 | for i := 0; i < len(t.text); i++ { 110 | drawText += "*" 111 | } 112 | } else { 113 | drawText = t.text 114 | } 115 | 116 | t.font.SetStyle(t.bold, t.italic, t.underlined) 117 | t.font.SetColor(t.fontColor.R, t.fontColor.G, t.fontColor.B) 118 | t.font.DrawTextInRect(drawText, drawArea.X + textX, drawArea.Y + textY, inRect) 119 | 120 | caretX = t.font.GetStringWidth(drawText) 121 | } 122 | 123 | //draw caret 124 | if t.caret && !t.readonly && t.focus { 125 | caretX += textX 126 | if inRect.Contains(drawArea.X+caretX, drawArea.Y+textY) { 127 | DrawLine(t.fontColor.R, t.fontColor.G, t.fontColor.B, 255, drawArea.X+caretX, drawArea.Y+textY, drawArea.X+caretX, drawArea.Y+textY+t.font.GetStringHeight()) 128 | } 129 | } 130 | if sdl.GetTicks()-t.caretLast >= CARET_TIME { 131 | t.caret = !t.caret 132 | t.caretLast = sdl.GetTicks() 133 | } 134 | } 135 | 136 | func (t *TextField) MouseUp(x, y int) { 137 | if t.Rect().Contains(x, y) { 138 | if window := t.Window(); window != nil { 139 | window.FocusElement(t) 140 | } 141 | } 142 | } 143 | 144 | -------------------------------------------------------------------------------- /go2d/gui/window.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | type IWindow interface { 4 | NextFocus() 5 | FocusElement(element IElement) 6 | } 7 | 8 | type Window struct { 9 | Container 10 | 11 | title string 12 | 13 | popups []*Window 14 | } 15 | 16 | func NewWindow(x, y, width, height int) *Window { 17 | window := &Window{} 18 | window.Init(x, y, width, height) 19 | return window 20 | } 21 | 22 | func (w *Window) AddChild(element IElement) { 23 | element.SetParent(w) 24 | w.children = append(w.children, element) 25 | } 26 | 27 | func (w *Window) KeyDown(button int) { 28 | if button == KEY_TAB { 29 | w.NextFocus() 30 | } else { 31 | w.Container.KeyDown(button) 32 | } 33 | } 34 | 35 | func (w *Window) NextFocus() { 36 | var elements []IElement = make([]IElement, 0) 37 | w.FillFocusList(&elements) 38 | 39 | if len(elements) > 0 { 40 | if len(elements) > 1 { 41 | currentFocusIndex := 0 42 | for index, element := range elements { 43 | if element.Focus() { 44 | currentFocusIndex = index 45 | } 46 | element.SetFocus(false) 47 | } 48 | 49 | currentFocusIndex++ 50 | if currentFocusIndex > (len(elements)-1) { 51 | currentFocusIndex = 0 52 | } 53 | 54 | elements[currentFocusIndex].SetFocus(true) 55 | } else { 56 | elements[0].SetFocus(true) 57 | } 58 | } 59 | } 60 | 61 | func (w *Window) FocusElement(element IElement) { 62 | var elements []IElement = make([]IElement, 0) 63 | w.FillFocusList(&elements) 64 | 65 | for _, elem := range elements { 66 | elem.SetFocus(false) 67 | } 68 | 69 | element.SetFocus(true) 70 | } -------------------------------------------------------------------------------- /go2d/image.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import ( 4 | "sdl" 5 | ) 6 | 7 | type Image struct { 8 | Width, Height uint16 9 | blendmode int 10 | 11 | surface *sdl.Surface 12 | texture *sdl.Texture 13 | } 14 | 15 | //Load image from file 16 | func NewImage(_file string) *Image { 17 | image := &Image{blendmode: sdl.BLENDMODE_BLEND} 18 | addResource(image) 19 | 20 | image.surface = sdl.LoadImage(GetPath() + _file) 21 | 22 | image.reload() 23 | return image 24 | } 25 | 26 | //Internal: load image from sdl surface 27 | func newImageFromSurface(_surface *sdl.Surface) *Image { 28 | image := &Image{surface: _surface, 29 | blendmode: sdl.BLENDMODE_BLEND} 30 | addResource(image) 31 | image.reload() 32 | return image 33 | } 34 | 35 | //Internal: create texture to render 36 | func (image *Image) reload() { 37 | image.texture = image.surface.CreateTexture(g_game.renderer) 38 | image.Width = uint16(image.texture.W) 39 | image.Height = uint16(image.texture.H) 40 | } 41 | 42 | //Internal: release the image's resources 43 | func (image *Image) release() { 44 | if image.surface != nil { 45 | image.surface.Release() 46 | } 47 | if image.texture != nil { 48 | image.texture.Release() 49 | } 50 | } 51 | 52 | //Set the blendmode (BLENDMODE_NONE, BLENDMODE_BLEND, BLENDMODE_ADD, BLENDMODE_MOD) 53 | func (image *Image) SetBlendMode(_blendmode int) { 54 | image.blendmode = _blendmode 55 | image.texture.SetBlendMode(_blendmode) 56 | } 57 | 58 | //Set the color modifier (used for color blending) 59 | func (image *Image) SetColorMod(_red uint8, _green uint8, _blue uint8) { 60 | image.texture.SetColorMod(_red, _green, _blue) 61 | } 62 | 63 | //Set the alpha value (transparency (0 for transparent - 255 for opaque) 64 | func (image *Image) SetAlphaMod(_alpha uint8) { 65 | image.texture.SetAlpha(_alpha) 66 | } 67 | 68 | //Internal: render image to buffer 69 | func (image *Image) render(_src *sdl.Rect, _dst *sdl.Rect) { 70 | image.texture.SetBlendMode(image.blendmode) 71 | image.texture.RenderCopy(g_game.renderer, _src, _dst) 72 | } 73 | 74 | //Draw image at given coordinates 75 | func (image *Image) Draw(_x, _y int) { 76 | src := &sdl.Rect{0, 0, int32(image.Width), int32(image.Height)} 77 | dst := &sdl.Rect{int32(_x), int32(_y), int32(image.Width), int32(image.Height)} 78 | 79 | image.render(src, dst) 80 | } 81 | 82 | //Draw the image as a rect (e.g. can be stretched) at the given coordinates 83 | func (image *Image) DrawRect(_rect *Rect) { 84 | src := &sdl.Rect{0, 0, int32(image.Width), int32(image.Height)} 85 | 86 | image.render(src, _rect.toSDL()) 87 | } 88 | 89 | //Draw a part of the image on the given coordinates 90 | func (image *Image) DrawClip(_x, _y int, _clip *Rect) { 91 | dst := &sdl.Rect{0, 0, int32(image.Width), int32(image.Height)} 92 | 93 | image.render(_clip.toSDL(), dst) 94 | } 95 | 96 | //Draw a part of the image as a rect (e.g. can be stretched) at the given coordinates 97 | func (image *Image) DrawRectClip(_rect *Rect, _clip *Rect) { 98 | image.render(_clip.toSDL(), _rect.toSDL()) 99 | } 100 | 101 | //Draw the image within a rect (cut off pieces that fall outside of the rect) 102 | func (image *Image) DrawInRect(_x, _y int, _inrect *Rect) { 103 | imgRect := NewRect(_x, _y, int(image.Width), int(image.Height)) 104 | inRect := _inrect.Intersection(imgRect) 105 | dstRect := NewRect(inRect.X, inRect.Y, inRect.Width, inRect.Height) 106 | inRect.X -= _x 107 | inRect.Y -= _y 108 | 109 | image.render(inRect.toSDL(), dstRect.toSDL()) 110 | } 111 | 112 | //Draw the image as a rect (e.g. can be stretched) within a rect (cut off pieces that fall outside of the rect) 113 | func (image *Image) DrawRectInRect(_rect *Rect, _inrect *Rect) { 114 | inRect := _inrect.Intersection(_rect) 115 | dstRect := NewRect(inRect.X, inRect.Y, inRect.Width, inRect.Height) 116 | inRect.X -= _rect.X 117 | inRect.Y -= _rect.Y 118 | 119 | image.render(inRect.toSDL(), dstRect.toSDL()) 120 | } 121 | -------------------------------------------------------------------------------- /go2d/rect.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import "sdl" 4 | 5 | type Rect struct { 6 | X, Y, Width, Height int 7 | } 8 | 9 | func NewRect(_x int, _y int, _width int, _height int) *Rect { 10 | return &Rect{X: _x, Y: _y, Width: _width, Height: _height} 11 | } 12 | 13 | func NewRectFrom(_rect *Rect) *Rect { 14 | return NewRect(_rect.X, _rect.Y, _rect.Width, _rect.Height) 15 | } 16 | 17 | func (rect *Rect) Equals(_rect *Rect) bool { 18 | return ((rect.X == _rect.X) && (rect.Y == _rect.Y) && (rect.Width == _rect.Width) && (rect.Height == _rect.Height)) 19 | } 20 | 21 | func (rect *Rect) Contains(_x int, _y int) bool { 22 | return (_x >= rect.X && _x <= rect.X+rect.Width && _y >= rect.Y && _y <= rect.Y+rect.Height) 23 | } 24 | 25 | func (rect *Rect) ContainsRect(_rect *Rect) bool { 26 | return (rect.Contains(_rect.X, _rect.Y) && 27 | rect.Contains(_rect.X+_rect.Width, _rect.Y) && 28 | rect.Contains(_rect.X, _rect.Y+_rect.Height) && 29 | rect.Contains(_rect.X+_rect.Width, _rect.Y+_rect.Height)) 30 | } 31 | 32 | func (rect *Rect) Intersects(_rect *Rect) bool { 33 | return !(rect.X > _rect.X+_rect.Width || _rect.X > rect.X+rect.Width || 34 | rect.Y > _rect.Y+_rect.Height || _rect.Y > rect.Y+rect.Height) 35 | } 36 | 37 | func (rect *Rect) Intersection(_rect *Rect) *Rect { 38 | if rect.Intersects(_rect) { 39 | tempX := _rect.X 40 | if rect.X > _rect.X { 41 | tempX = rect.X 42 | } 43 | 44 | tempY := _rect.Y 45 | if rect.Y > _rect.Y { 46 | tempY = rect.Y 47 | } 48 | 49 | tempW := _rect.X + _rect.Width 50 | if rect.X+rect.Width < _rect.X+_rect.Width { 51 | tempW = rect.X + rect.Width 52 | } 53 | 54 | tempH := _rect.Y + _rect.Height 55 | if rect.Y+rect.Height < _rect.Y+_rect.Height { 56 | tempH = rect.Y + rect.Height 57 | } 58 | 59 | tempW -= tempX 60 | tempH -= tempY 61 | 62 | return NewRect(tempX, tempY, tempW, tempH) 63 | } 64 | return NewRect(0, 0, 0, 0) 65 | } 66 | 67 | //Internal: convert Rect to sdl.Rect 68 | func (rect *Rect) toSDL() *sdl.Rect { 69 | return &sdl.Rect{int32(rect.X), int32(rect.Y), int32(rect.Width), int32(rect.Height)} 70 | } 71 | -------------------------------------------------------------------------------- /go2d/resource.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import "container/list" 4 | 5 | var g_resources *list.List = list.New() 6 | 7 | type IResource interface { 8 | release() 9 | } 10 | 11 | func addResource(_resource IResource) { 12 | g_resources.PushBack(_resource) 13 | } 14 | 15 | func freeResources() { 16 | for i := g_resources.Front(); i != nil; i = i.Next() { 17 | res, valid := i.Value.(IResource) 18 | if valid { 19 | res.release() 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /go2d/tools.go: -------------------------------------------------------------------------------- 1 | package go2d 2 | 3 | import ( 4 | "sdl" 5 | "exec" 6 | "path" 7 | "os" 8 | ) 9 | 10 | func Sleep(_ticks uint32) { 11 | sdl.Delay(_ticks) 12 | } 13 | 14 | func GetTicks() uint32 { 15 | return sdl.GetTicks() 16 | } 17 | 18 | func KeyDown(_key int) bool { 19 | return sdl.KeyDown(_key) 20 | } 21 | 22 | func GetPath() string { 23 | file, _ := exec.LookPath(os.Args[0]) 24 | dir, _ := path.Split(file) 25 | os.Chdir(dir) 26 | path, _ := os.Getwd() 27 | return path + "/" 28 | } 29 | 30 | func DrawFillRect(_rect *Rect, _red, _green, _blue, _alpha uint8) { 31 | sdl.SetRenderDrawColor(g_game.renderer, _red, _green, _blue, _alpha) 32 | sdl.SetRenderDrawBlendMode(g_game.renderer, sdl.BLENDMODE_BLEND) 33 | sdl.RenderFillRect(g_game.renderer, *_rect.toSDL()) 34 | sdl.SetRenderDrawBlendMode(g_game.renderer, sdl.BLENDMODE_NONE) 35 | sdl.SetRenderDrawColor(g_game.renderer, 0, 0, 0, 255) 36 | } 37 | 38 | func DrawRect(_rect *Rect, _red, _green, _blue, _alpha uint8) { 39 | sdl.SetRenderDrawColor(g_game.renderer, _red, _green, _blue, _alpha) 40 | sdl.SetRenderDrawBlendMode(g_game.renderer, sdl.BLENDMODE_BLEND) 41 | sdl.RenderDrawRect(g_game.renderer, *_rect.toSDL()) 42 | sdl.SetRenderDrawBlendMode(g_game.renderer, sdl.BLENDMODE_NONE) 43 | sdl.SetRenderDrawColor(g_game.renderer, 0, 0, 0, 255) 44 | } 45 | 46 | func DrawLine(_red, _green, _blue, _alpha uint8, _x1, _y1, _x2, _y2 int) { 47 | sdl.SetRenderDrawColor(g_game.renderer, _red, _green, _blue, _alpha) 48 | sdl.SetRenderDrawBlendMode(g_game.renderer, sdl.BLENDMODE_BLEND) 49 | sdl.RenderDrawLine(g_game.renderer, _x1, _y1, _x2, _y2) 50 | sdl.SetRenderDrawBlendMode(g_game.renderer, sdl.BLENDMODE_NONE) 51 | sdl.SetRenderDrawColor(g_game.renderer, 0, 0, 0, 255) 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /screenshot_linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PikeDev/Go2D/0e8a27a19b89ed437b17cbc8f8f2b74bff56e4f4/screenshot_linux.png -------------------------------------------------------------------------------- /screenshot_windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PikeDev/Go2D/0e8a27a19b89ed437b17cbc8f8f2b74bff56e4f4/screenshot_windows.png -------------------------------------------------------------------------------- /sdl/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2009 The Go Authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style 3 | # license that can be found in the LICENSE file. 4 | 5 | include $(GOROOT)/src/Make.inc 6 | 7 | TARG=sdl 8 | CGOFILES=\ 9 | sdl.go\ 10 | ttf.go\ 11 | image.go\ 12 | renderer.go\ 13 | event.go\ 14 | const.go\ 15 | 16 | CGO_CFLAGS=`sdl-config --cflags` 17 | CGO_LDFLAGS=`sdl-config --libs` -lSDL_image -lSDL_ttf 18 | 19 | CLEANFILES+=sdl 20 | 21 | include $(GOROOT)/src/Make.pkg 22 | 23 | %: install %.go 24 | $(GC) $*.go 25 | $(LD) -o $@ $*.$O 26 | -------------------------------------------------------------------------------- /sdl/const.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | //#include 4 | import "C" 5 | 6 | const ( 7 | SDL_INIT_VIDEO = C.SDL_INIT_VIDEO 8 | SDL_INIT_TIMER = C.SDL_INIT_TIMER 9 | 10 | SDL_WINDOWPOS_CENTERED = C.SDL_WINDOWPOS_CENTERED 11 | SDL_WINDOW_SHOWN = C.SDL_WINDOW_SHOWN 12 | SDL_RENDERER_PRESENTVSYNC = C.SDL_RENDERER_PRESENTVSYNC 13 | SDL_RENDERER_ACCELERATED = C.SDL_RENDERER_ACCELERATED 14 | 15 | BLENDMODE_NONE = C.SDL_BLENDMODE_NONE 16 | BLENDMODE_BLEND = C.SDL_BLENDMODE_BLEND 17 | BLENDMODE_ADD = C.SDL_BLENDMODE_ADD 18 | BLENDMODE_MOD = C.SDL_BLENDMODE_MOD 19 | 20 | /* Window events */ 21 | SDL_WINDOWEVENT_NONE = C.SDL_WINDOWEVENT_NONE 22 | SDL_WINDOWEVENT_SHOWN = C.SDL_WINDOWEVENT_SHOWN 23 | SDL_WINDOWEVENT_HIDDEN = C.SDL_WINDOWEVENT_HIDDEN 24 | SDL_WINDOWEVENT_EXPOSED = C.SDL_WINDOWEVENT_EXPOSED 25 | SDL_WINDOWEVENT_MOVED = C.SDL_WINDOWEVENT_MOVED 26 | SDL_WINDOWEVENT_RESIZED = C.SDL_WINDOWEVENT_RESIZED 27 | SDL_WINDOWEVENT_SIZE_CHANGED = C.SDL_WINDOWEVENT_SIZE_CHANGED 28 | SDL_WINDOWEVENT_MINIMIZED = C.SDL_WINDOWEVENT_MINIMIZED 29 | SDL_WINDOWEVENT_MAXIMIZED = C.SDL_WINDOWEVENT_MAXIMIZED 30 | SDL_WINDOWEVENT_RESTORED = C.SDL_WINDOWEVENT_RESTORED 31 | SDL_WINDOWEVENT_ENTER = C.SDL_WINDOWEVENT_ENTER 32 | SDL_WINDOWEVENT_LEAVE = C.SDL_WINDOWEVENT_LEAVE 33 | SDL_WINDOWEVENT_FOCUS_GAINED = C.SDL_WINDOWEVENT_FOCUS_GAINED 34 | SDL_WINDOWEVENT_FOCUS_LOST = C.SDL_WINDOWEVENT_FOCUS_LOST 35 | SDL_WINDOWEVENT_CLOSE = C.SDL_WINDOWEVENT_CLOSE 36 | 37 | SDL_QUIT = C.SDL_QUIT 38 | SDL_WINDOWEVENT = C.SDL_WINDOWEVENT 39 | SDL_SYSWMEVENT = C.SDL_SYSWMEVENT 40 | 41 | /* Keyboard events */ 42 | SDL_KEYDOWN = C.SDL_KEYDOWN 43 | SDL_KEYUP = C.SDL_KEYUP 44 | SDL_TEXTEDITING = C.SDL_TEXTEDITING 45 | SDL_TEXTINPUT = C.SDL_TEXTINPUT 46 | 47 | /* Mouse events */ 48 | SDL_MOUSEMOTION = C.SDL_MOUSEMOTION 49 | SDL_MOUSEBUTTONDOWN = C.SDL_MOUSEBUTTONDOWN 50 | SDL_MOUSEBUTTONUP = C.SDL_MOUSEBUTTONUP 51 | SDL_MOUSEWHEEL = C.SDL_MOUSEWHEEL 52 | SCROLL_UP = 0 53 | SCROLL_DOWN = 1 54 | ) 55 | 56 | const ( 57 | KEY_UNKNOWN = C.SDL_SCANCODE_UNKNOWN 58 | KEY_A = C.SDL_SCANCODE_A 59 | KEY_B = C.SDL_SCANCODE_B 60 | KEY_C = C.SDL_SCANCODE_C 61 | KEY_D = C.SDL_SCANCODE_D 62 | KEY_E = C.SDL_SCANCODE_E 63 | KEY_F = C.SDL_SCANCODE_F 64 | KEY_G = C.SDL_SCANCODE_G 65 | KEY_H = C.SDL_SCANCODE_H 66 | KEY_I = C.SDL_SCANCODE_I 67 | KEY_J = C.SDL_SCANCODE_J 68 | KEY_K = C.SDL_SCANCODE_K 69 | KEY_L = C.SDL_SCANCODE_L 70 | KEY_M = C.SDL_SCANCODE_M 71 | KEY_N = C.SDL_SCANCODE_N 72 | KEY_O = C.SDL_SCANCODE_O 73 | KEY_P = C.SDL_SCANCODE_P 74 | KEY_Q = C.SDL_SCANCODE_Q 75 | KEY_R = C.SDL_SCANCODE_R 76 | KEY_S = C.SDL_SCANCODE_S 77 | KEY_T = C.SDL_SCANCODE_T 78 | KEY_U = C.SDL_SCANCODE_U 79 | KEY_V = C.SDL_SCANCODE_V 80 | KEY_W = C.SDL_SCANCODE_W 81 | KEY_X = C.SDL_SCANCODE_X 82 | KEY_Y = C.SDL_SCANCODE_Y 83 | KEY_Z = C.SDL_SCANCODE_Z 84 | KEY_1 = C.SDL_SCANCODE_1 85 | KEY_2 = C.SDL_SCANCODE_2 86 | KEY_3 = C.SDL_SCANCODE_3 87 | KEY_4 = C.SDL_SCANCODE_4 88 | KEY_5 = C.SDL_SCANCODE_5 89 | KEY_6 = C.SDL_SCANCODE_6 90 | KEY_7 = C.SDL_SCANCODE_7 91 | KEY_8 = C.SDL_SCANCODE_8 92 | KEY_9 = C.SDL_SCANCODE_9 93 | KEY_0 = C.SDL_SCANCODE_0 94 | KEY_RETURN = C.SDL_SCANCODE_RETURN 95 | KEY_ESCAPE = C.SDL_SCANCODE_ESCAPE 96 | KEY_BACKSPACE = C.SDL_SCANCODE_BACKSPACE 97 | KEY_TAB = C.SDL_SCANCODE_TAB 98 | KEY_SPACE = C.SDL_SCANCODE_SPACE 99 | KEY_MINUS = C.SDL_SCANCODE_MINUS 100 | KEY_EQUALS = C.SDL_SCANCODE_EQUALS 101 | KEY_LEFTBRACKET = C.SDL_SCANCODE_LEFTBRACKET 102 | KEY_RIGHTBRACKET = C.SDL_SCANCODE_RIGHTBRACKET 103 | KEY_BACKSLASH = C.SDL_SCANCODE_BACKSLASH 104 | KEY_NONUSHASH = C.SDL_SCANCODE_NONUSHASH 105 | KEY_SEMICOLON = C.SDL_SCANCODE_SEMICOLON 106 | KEY_APOSTROPHE = C.SDL_SCANCODE_APOSTROPHE 107 | KEY_GRAVE = C.SDL_SCANCODE_GRAVE 108 | KEY_COMMA = C.SDL_SCANCODE_COMMA 109 | KEY_PERIOD = C.SDL_SCANCODE_PERIOD 110 | KEY_SLASH = C.SDL_SCANCODE_SLASH 111 | KEY_CAPSLOCK = C.SDL_SCANCODE_CAPSLOCK 112 | KEY_F1 = C.SDL_SCANCODE_F1 113 | KEY_F2 = C.SDL_SCANCODE_F2 114 | KEY_F3 = C.SDL_SCANCODE_F3 115 | KEY_F4 = C.SDL_SCANCODE_F4 116 | KEY_F5 = C.SDL_SCANCODE_F5 117 | KEY_F6 = C.SDL_SCANCODE_F6 118 | KEY_F7 = C.SDL_SCANCODE_F7 119 | KEY_F8 = C.SDL_SCANCODE_F8 120 | KEY_F9 = C.SDL_SCANCODE_F9 121 | KEY_F10 = C.SDL_SCANCODE_F10 122 | KEY_F11 = C.SDL_SCANCODE_F11 123 | KEY_F12 = C.SDL_SCANCODE_F12 124 | KEY_PRINTSCREEN = C.SDL_SCANCODE_PRINTSCREEN 125 | KEY_SCROLLLOCK = C.SDL_SCANCODE_SCROLLLOCK 126 | KEY_PAUSE = C.SDL_SCANCODE_PAUSE 127 | KEY_INSERT = C.SDL_SCANCODE_INSERT 128 | KEY_HOME = C.SDL_SCANCODE_HOME 129 | KEY_PAGEUP = C.SDL_SCANCODE_PAGEUP 130 | KEY_DELETE = C.SDL_SCANCODE_DELETE 131 | KEY_END = C.SDL_SCANCODE_END 132 | KEY_PAGEDOWN = C.SDL_SCANCODE_PAGEDOWN 133 | KEY_RIGHT = C.SDL_SCANCODE_RIGHT 134 | KEY_LEFT = C.SDL_SCANCODE_LEFT 135 | KEY_DOWN = C.SDL_SCANCODE_DOWN 136 | KEY_UP = C.SDL_SCANCODE_UP 137 | KEY_NUMLOCKCLEAR = C.SDL_SCANCODE_NUMLOCKCLEAR 138 | KEY_KP_DIVIDE = C.SDL_SCANCODE_KP_DIVIDE 139 | KEY_KP_MULTIPLY = C.SDL_SCANCODE_KP_MULTIPLY 140 | KEY_KP_MINUS = C.SDL_SCANCODE_KP_MINUS 141 | KEY_KP_PLUS = C.SDL_SCANCODE_KP_PLUS 142 | KEY_KP_ENTER = C.SDL_SCANCODE_KP_ENTER 143 | KEY_KP_1 = C.SDL_SCANCODE_KP_1 144 | KEY_KP_2 = C.SDL_SCANCODE_KP_2 145 | KEY_KP_3 = C.SDL_SCANCODE_KP_3 146 | KEY_KP_4 = C.SDL_SCANCODE_KP_4 147 | KEY_KP_5 = C.SDL_SCANCODE_KP_5 148 | KEY_KP_6 = C.SDL_SCANCODE_KP_6 149 | KEY_KP_7 = C.SDL_SCANCODE_KP_7 150 | KEY_KP_8 = C.SDL_SCANCODE_KP_8 151 | KEY_KP_9 = C.SDL_SCANCODE_KP_9 152 | KEY_KP_0 = C.SDL_SCANCODE_KP_0 153 | KEY_KP_PERIOD = C.SDL_SCANCODE_KP_PERIOD 154 | KEY_NONUSBACKSLASH = C.SDL_SCANCODE_NONUSBACKSLASH 155 | KEY_APPLICATION = C.SDL_SCANCODE_APPLICATION 156 | KEY_POWER = C.SDL_SCANCODE_POWER 157 | KEY_KP_EQUALS = C.SDL_SCANCODE_KP_EQUALS 158 | KEY_F13 = C.SDL_SCANCODE_F13 159 | KEY_F14 = C.SDL_SCANCODE_F14 160 | KEY_F15 = C.SDL_SCANCODE_F15 161 | KEY_F16 = C.SDL_SCANCODE_F16 162 | KEY_F17 = C.SDL_SCANCODE_F17 163 | KEY_F18 = C.SDL_SCANCODE_F18 164 | KEY_F19 = C.SDL_SCANCODE_F19 165 | KEY_F20 = C.SDL_SCANCODE_F20 166 | KEY_F21 = C.SDL_SCANCODE_F21 167 | KEY_F22 = C.SDL_SCANCODE_F22 168 | KEY_F23 = C.SDL_SCANCODE_F23 169 | KEY_F24 = C.SDL_SCANCODE_F24 170 | KEY_EXECUTE = C.SDL_SCANCODE_EXECUTE 171 | KEY_HELP = C.SDL_SCANCODE_HELP 172 | KEY_MENU = C.SDL_SCANCODE_MENU 173 | KEY_SELECT = C.SDL_SCANCODE_SELECT 174 | KEY_STOP = C.SDL_SCANCODE_STOP 175 | KEY_AGAIN = C.SDL_SCANCODE_AGAIN 176 | KEY_UNDO = C.SDL_SCANCODE_UNDO 177 | KEY_CUT = C.SDL_SCANCODE_CUT 178 | KEY_COPY = C.SDL_SCANCODE_COPY 179 | KEY_PASTE = C.SDL_SCANCODE_PASTE 180 | KEY_FIND = C.SDL_SCANCODE_FIND 181 | KEY_MUTE = C.SDL_SCANCODE_MUTE 182 | KEY_VOLUMEUP = C.SDL_SCANCODE_VOLUMEUP 183 | KEY_VOLUMEDOWN = C.SDL_SCANCODE_VOLUMEDOWN 184 | KEY_KP_COMMA = C.SDL_SCANCODE_KP_COMMA 185 | KEY_KP_EQUALSAS400 = C.SDL_SCANCODE_KP_EQUALSAS400 186 | KEY_INTERNATIONAL1 = C.SDL_SCANCODE_INTERNATIONAL1 187 | KEY_INTERNATIONAL2 = C.SDL_SCANCODE_INTERNATIONAL2 188 | KEY_INTERNATIONAL3 = C.SDL_SCANCODE_INTERNATIONAL3 189 | KEY_INTERNATIONAL4 = C.SDL_SCANCODE_INTERNATIONAL4 190 | KEY_INTERNATIONAL5 = C.SDL_SCANCODE_INTERNATIONAL5 191 | KEY_INTERNATIONAL6 = C.SDL_SCANCODE_INTERNATIONAL6 192 | KEY_INTERNATIONAL7 = C.SDL_SCANCODE_INTERNATIONAL7 193 | KEY_INTERNATIONAL8 = C.SDL_SCANCODE_INTERNATIONAL8 194 | KEY_INTERNATIONAL9 = C.SDL_SCANCODE_INTERNATIONAL9 195 | KEY_LANG1 = C.SDL_SCANCODE_LANG1 196 | KEY_LANG2 = C.SDL_SCANCODE_LANG2 197 | KEY_LANG3 = C.SDL_SCANCODE_LANG3 198 | KEY_LANG4 = C.SDL_SCANCODE_LANG4 199 | KEY_LANG5 = C.SDL_SCANCODE_LANG5 200 | KEY_LANG6 = C.SDL_SCANCODE_LANG6 201 | KEY_LANG7 = C.SDL_SCANCODE_LANG7 202 | KEY_LANG8 = C.SDL_SCANCODE_LANG8 203 | KEY_LANG9 = C.SDL_SCANCODE_LANG9 204 | KEY_ALTERASE = C.SDL_SCANCODE_ALTERASE 205 | KEY_SYSREQ = C.SDL_SCANCODE_SYSREQ 206 | KEY_CANCEL = C.SDL_SCANCODE_CANCEL 207 | KEY_CLEAR = C.SDL_SCANCODE_CLEAR 208 | KEY_PRIOR = C.SDL_SCANCODE_PRIOR 209 | KEY_RETURN2 = C.SDL_SCANCODE_RETURN2 210 | KEY_SEPARATOR = C.SDL_SCANCODE_SEPARATOR 211 | KEY_OUT = C.SDL_SCANCODE_OUT 212 | KEY_OPER = C.SDL_SCANCODE_OPER 213 | KEY_CLEARAGAIN = C.SDL_SCANCODE_CLEARAGAIN 214 | KEY_CRSEL = C.SDL_SCANCODE_CRSEL 215 | KEY_EXSEL = C.SDL_SCANCODE_EXSEL 216 | KEY_KP_00 = C.SDL_SCANCODE_KP_00 217 | KEY_KP_000 = C.SDL_SCANCODE_KP_000 218 | KEY_THOUSANDSSEPARATOR = C.SDL_SCANCODE_THOUSANDSSEPARATOR 219 | KEY_DECIMALSEPARATOR = C.SDL_SCANCODE_DECIMALSEPARATOR 220 | KEY_CURRENCYUNIT = C.SDL_SCANCODE_CURRENCYUNIT 221 | KEY_CURRENCYSUBUNIT = C.SDL_SCANCODE_CURRENCYSUBUNIT 222 | KEY_KP_LEFTPAREN = C.SDL_SCANCODE_KP_LEFTPAREN 223 | KEY_KP_RIGHTPAREN = C.SDL_SCANCODE_KP_RIGHTPAREN 224 | KEY_KP_LEFTBRACE = C.SDL_SCANCODE_KP_LEFTBRACE 225 | KEY_KP_RIGHTBRACE = C.SDL_SCANCODE_KP_RIGHTBRACE 226 | KEY_KP_TAB = C.SDL_SCANCODE_KP_TAB 227 | KEY_KP_BACKSPACE = C.SDL_SCANCODE_KP_BACKSPACE 228 | KEY_KP_A = C.SDL_SCANCODE_KP_A 229 | KEY_KP_B = C.SDL_SCANCODE_KP_B 230 | KEY_KP_C = C.SDL_SCANCODE_KP_C 231 | KEY_KP_D = C.SDL_SCANCODE_KP_D 232 | KEY_KP_E = C.SDL_SCANCODE_KP_E 233 | KEY_KP_F = C.SDL_SCANCODE_KP_F 234 | KEY_KP_XOR = C.SDL_SCANCODE_KP_XOR 235 | KEY_KP_POWER = C.SDL_SCANCODE_KP_POWER 236 | KEY_KP_PERCENT = C.SDL_SCANCODE_KP_PERCENT 237 | KEY_KP_LESS = C.SDL_SCANCODE_KP_LESS 238 | KEY_KP_GREATER = C.SDL_SCANCODE_KP_GREATER 239 | KEY_KP_AMPERSAND = C.SDL_SCANCODE_KP_AMPERSAND 240 | KEY_KP_DBLAMPERSAND = C.SDL_SCANCODE_KP_DBLAMPERSAND 241 | KEY_KP_VERTICALBAR = C.SDL_SCANCODE_KP_VERTICALBAR 242 | KEY_KP_DBLVERTICALBAR = C.SDL_SCANCODE_KP_DBLVERTICALBAR 243 | KEY_KP_COLON = C.SDL_SCANCODE_KP_COLON 244 | KEY_KP_HASH = C.SDL_SCANCODE_KP_HASH 245 | KEY_KP_SPACE = C.SDL_SCANCODE_KP_SPACE 246 | KEY_KP_AT = C.SDL_SCANCODE_KP_AT 247 | KEY_KP_EXCLAM = C.SDL_SCANCODE_KP_EXCLAM 248 | KEY_KP_MEMSTORE = C.SDL_SCANCODE_KP_MEMSTORE 249 | KEY_KP_MEMRECALL = C.SDL_SCANCODE_KP_MEMRECALL 250 | KEY_KP_MEMCLEAR = C.SDL_SCANCODE_KP_MEMCLEAR 251 | KEY_KP_MEMADD = C.SDL_SCANCODE_KP_MEMADD 252 | KEY_KP_MEMSUBTRACT = C.SDL_SCANCODE_KP_MEMSUBTRACT 253 | KEY_KP_MEMMULTIPLY = C.SDL_SCANCODE_KP_MEMMULTIPLY 254 | KEY_KP_MEMDIVIDE = C.SDL_SCANCODE_KP_MEMDIVIDE 255 | KEY_KP_PLUSMINUS = C.SDL_SCANCODE_KP_PLUSMINUS 256 | KEY_KP_CLEAR = C.SDL_SCANCODE_KP_CLEAR 257 | KEY_KP_CLEARENTRY = C.SDL_SCANCODE_KP_CLEARENTRY 258 | KEY_KP_BINARY = C.SDL_SCANCODE_KP_BINARY 259 | KEY_KP_OCTAL = C.SDL_SCANCODE_KP_OCTAL 260 | KEY_KP_DECIMAL = C.SDL_SCANCODE_KP_DECIMAL 261 | KEY_KP_HEXADECIMAL = C.SDL_SCANCODE_KP_HEXADECIMAL 262 | KEY_LCTRL = C.SDL_SCANCODE_LCTRL 263 | KEY_LSHIFT = C.SDL_SCANCODE_LSHIFT 264 | KEY_LALT = C.SDL_SCANCODE_LALT 265 | KEY_LGUI = C.SDL_SCANCODE_LGUI 266 | KEY_RCTRL = C.SDL_SCANCODE_RCTRL 267 | KEY_RSHIFT = C.SDL_SCANCODE_RSHIFT 268 | KEY_RALT = C.SDL_SCANCODE_RALT 269 | KEY_RGUI = C.SDL_SCANCODE_RGUI 270 | KEY_MODE = C.SDL_SCANCODE_MODE 271 | KEY_AUDIONEXT = C.SDL_SCANCODE_AUDIONEXT 272 | KEY_AUDIOPREV = C.SDL_SCANCODE_AUDIOPREV 273 | KEY_AUDIOSTOP = C.SDL_SCANCODE_AUDIOSTOP 274 | KEY_AUDIOPLAY = C.SDL_SCANCODE_AUDIOPLAY 275 | KEY_AUDIOMUTE = C.SDL_SCANCODE_AUDIOMUTE 276 | KEY_MEDIASELECT = C.SDL_SCANCODE_MEDIASELECT 277 | KEY_WWW = C.SDL_SCANCODE_WWW 278 | KEY_MAIL = C.SDL_SCANCODE_MAIL 279 | KEY_CALCULATOR = C.SDL_SCANCODE_CALCULATOR 280 | KEY_COMPUTER = C.SDL_SCANCODE_COMPUTER 281 | KEY_AC_SEARCH = C.SDL_SCANCODE_AC_SEARCH 282 | KEY_AC_HOME = C.SDL_SCANCODE_AC_HOME 283 | KEY_AC_BACK = C.SDL_SCANCODE_AC_BACK 284 | KEY_AC_FORWARD = C.SDL_SCANCODE_AC_FORWARD 285 | KEY_AC_STOP = C.SDL_SCANCODE_AC_STOP 286 | KEY_AC_REFRESH = C.SDL_SCANCODE_AC_REFRESH 287 | KEY_AC_BOOKMARKS = C.SDL_SCANCODE_AC_BOOKMARKS 288 | KEY_BRIGHTNESSDOWN = C.SDL_SCANCODE_BRIGHTNESSDOWN 289 | KEY_BRIGHTNESSUP = C.SDL_SCANCODE_BRIGHTNESSUP 290 | KEY_DISPLAYSWITCH = C.SDL_SCANCODE_DISPLAYSWITCH 291 | KEY_KBDILLUMTOGGLE = C.SDL_SCANCODE_KBDILLUMTOGGLE 292 | KEY_KBDILLUMDOWN = C.SDL_SCANCODE_KBDILLUMDOWN 293 | KEY_KBDILLUMUP = C.SDL_SCANCODE_KBDILLUMUP 294 | KEY_EJECT = C.SDL_SCANCODE_EJECT 295 | KEY_SLEEP = C.SDL_SCANCODE_SLEEP 296 | ) 297 | -------------------------------------------------------------------------------- /sdl/event.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | //#include "SDL.h" 4 | import "C" 5 | 6 | type SDLEvent struct { 7 | Evtype uint32 8 | rest [48]byte 9 | } 10 | 11 | func (e *SDLEvent) Window() *WindowEvent { 12 | return (*WindowEvent)(cast(e)) 13 | } 14 | 15 | func (e *SDLEvent) Keyboard() *KeyboardEvent { 16 | return (*KeyboardEvent)(cast(e)) 17 | } 18 | 19 | func (e *SDLEvent) TextEdit() *TextEditingEvent { 20 | return (*TextEditingEvent)(cast(e)) 21 | } 22 | 23 | func (e *SDLEvent) TextInput() *TextInputEvent { 24 | return (*TextInputEvent)(cast(e)) 25 | } 26 | 27 | func (e *SDLEvent) MouseMotion() *MouseMotionEvent { 28 | return (*MouseMotionEvent)(cast(e)) 29 | } 30 | 31 | func (e *SDLEvent) MouseButton() *MouseButtonEvent { 32 | return (*MouseButtonEvent)(cast(e)) 33 | } 34 | 35 | func (e *SDLEvent) MouseWheel() *MouseWheelEvent { 36 | return (*MouseWheelEvent)(cast(e)) 37 | } 38 | 39 | func (e *SDLEvent) Quit() *QuitEvent { 40 | return (*QuitEvent)(cast(e)) 41 | } 42 | 43 | func (e *SDLEvent) User() *UserEvent { 44 | return (*UserEvent)(cast(e)) 45 | } 46 | 47 | func (e *SDLEvent) SysWM() *SysWMEvent { 48 | return (*SysWMEvent)(cast(e)) 49 | } 50 | 51 | type WindowEvent struct { 52 | Evtype uint32 53 | WindowID uint32 54 | Event uint8 55 | Padding1 uint8 56 | Padding2 uint8 57 | Padding3 uint8 58 | Data1 int32 59 | Data2 int32 60 | } 61 | 62 | type KeyboardEvent struct { 63 | Evtype uint32 64 | WindowID uint32 65 | State uint8 66 | Repeat uint8 67 | Padding2 uint8 68 | Padding3 uint8 69 | keysym C.SDL_keysym 70 | } 71 | 72 | func (e *KeyboardEvent) Keysym() *KeySym { 73 | return (*KeySym)(cast(&e.keysym)) 74 | } 75 | 76 | type KeySym struct { 77 | Scancode int32//C.enum_SDL_scancode 78 | Sym int32 79 | Mod uint16 80 | Unicode uint32 81 | } 82 | 83 | type TextEditingEvent struct { 84 | Evtype uint32 85 | WindowID uint32 86 | Text [32]byte 87 | Start int32 88 | Length int32 89 | } 90 | 91 | type TextInputEvent struct { 92 | Evtype uint32 93 | WindowID uint32 94 | Text [32]byte 95 | } 96 | 97 | type MouseMotionEvent struct { 98 | Evtype uint32 99 | WindowID uint32 100 | State uint8 101 | Padding1 uint8 102 | Padding2 uint8 103 | Padding3 uint8 104 | X int32 105 | Y int32 106 | Xrel int32 107 | Yrel int32 108 | } 109 | 110 | type MouseButtonEvent struct { 111 | Evtype uint32 112 | WindowID uint32 113 | Button uint8 114 | State uint8 115 | Padding1 uint8 116 | Padding2 uint8 117 | X int32 118 | Y int32 119 | } 120 | 121 | type MouseWheelEvent struct { 122 | Evtype uint32 123 | WindowID uint32 124 | X int32 125 | Y int32 126 | } 127 | 128 | type QuitEvent struct { 129 | Evtype uint32 130 | } 131 | 132 | type UserEvent struct { 133 | Evtype uint32 134 | WindowID uint32 135 | Code int32 136 | Data1 *[0]byte 137 | Cata2 *[0]byte 138 | } 139 | 140 | type SysWMEvent struct { 141 | Evtype uint32 142 | } 143 | -------------------------------------------------------------------------------- /sdl/image.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | /* 4 | #include "SDL.h" 5 | #include "SDL_image.h" 6 | */ 7 | import "C" 8 | import ( 9 | "unsafe" 10 | "fmt" 11 | ) 12 | 13 | type Surface C.SDL_Surface 14 | 15 | func (s *Surface) Get() *C.SDL_Surface { 16 | return (*C.SDL_Surface)(s) 17 | } 18 | 19 | func (s *Surface) Release() { 20 | C.SDL_FreeSurface(s.Get()) 21 | } 22 | 23 | func (s *Surface) CreateTexture(_renderer *Renderer) *Texture { 24 | var tex = C.SDL_CreateTextureFromSurface(_renderer.Get(), s.Get()) 25 | return (*Texture)(cast(tex)) 26 | } 27 | 28 | func (s *Surface) DisplayFormatAlpha() *Surface { 29 | return (*Surface)(C.SDL_DisplayFormatAlpha(s.Get())) 30 | } 31 | 32 | func (s *Surface) SaveBMP(_file string) { 33 | cfile := C.CString(_file); defer C.free(unsafe.Pointer(cfile)) 34 | cparams := C.CString("wb"); defer C.free(unsafe.Pointer(cparams)) 35 | C.SDL_SaveBMP_RW(s.Get(), C.SDL_RWFromFile(cfile, cparams), C.int(1)) 36 | } 37 | 38 | func LoadBMP(_file string) *Surface { 39 | cfile := C.CString(_file); defer C.free(unsafe.Pointer(cfile)) 40 | cparams := C.CString("rb"); defer C.free(unsafe.Pointer(cparams)) 41 | return (*Surface)(C.SDL_LoadBMP_RW(C.SDL_RWFromFile(cfile, cparams), C.int(1))) 42 | } 43 | 44 | func LoadImage(_file string) *Surface { 45 | cfile := C.CString(_file); defer C.free(unsafe.Pointer(cfile)) 46 | img := C.IMG_Load(cfile) 47 | if img == nil { 48 | fmt.Printf("Image load error: %v", C.GoString(C.IMG_GetError())) 49 | } 50 | return (*Surface)(cast(img)) 51 | } 52 | 53 | func LoadImageRW(_data *[]byte, _size int) *Surface { 54 | rawImage := C.SDL_RWFromMem(unsafe.Pointer(&((*_data)[0])), C.int(_size)); 55 | img := C.IMG_Load_RW(rawImage, C.int(0)) 56 | if img == nil { 57 | fmt.Printf("ImageRW load error: %v", C.GoString(C.IMG_GetError())) 58 | } 59 | return (*Surface)(cast(img)) 60 | } 61 | 62 | type Rect struct { 63 | X int32 64 | Y int32 65 | W int32 66 | H int32 67 | } 68 | 69 | type Color struct { 70 | R uint8 71 | G uint8 72 | B uint8 73 | Unused uint8 74 | } 75 | -------------------------------------------------------------------------------- /sdl/renderer.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | //#include "SDL.h" 4 | import "C" 5 | import "unsafe" 6 | 7 | type Texture struct { 8 | Magic *[0]byte 9 | Format uint32 10 | Access int32 11 | W int32 12 | H int32 13 | ModMode int32 14 | BlendMode *C.SDL_BlendMode 15 | R, G, B, A uint8 16 | 17 | Native *Texture 18 | Yuv *[0]byte 19 | 20 | Pixels *[0]byte 21 | 22 | Pitch int32 23 | Locked_rect Rect 24 | 25 | Driverdata *[0]byte 26 | 27 | Prev *Texture 28 | Next *Texture 29 | } 30 | 31 | func (t *Texture) Get() *C.SDL_Texture { 32 | return (*C.SDL_Texture)(cast(t)) 33 | } 34 | 35 | func (t *Texture) Release() { 36 | C.SDL_DestroyTexture(t.Get()) 37 | } 38 | 39 | func (t *Texture) SetAlpha(_alpha uint8) { 40 | C.SDL_SetTextureAlphaMod(t.Get(), C.Uint8(_alpha)) 41 | } 42 | 43 | func (t *Texture) RenderCopy(_renderer *Renderer, _srcrect *Rect, _dstrect *Rect) { 44 | src := (*C.SDL_Rect)(cast(_srcrect)) 45 | dst := (*C.SDL_Rect)(cast(_dstrect)) 46 | C.SDL_RenderCopy(_renderer.Get(), t.Get(), src, dst) 47 | } 48 | 49 | func (t *Texture) SetColorMod(_red uint8, _green uint8, _blue uint8) { 50 | C.SDL_SetTextureColorMod(t.Get(), C.Uint8(_red), C.Uint8(_green), C.Uint8(_blue)) 51 | } 52 | 53 | func (t *Texture) SetBlendMode(_blendmode int) { 54 | C.SDL_SetTextureBlendMode(t.Get(), C.SDL_BlendMode(_blendmode)) 55 | } 56 | 57 | func GetNumRenderDrivers() int { 58 | return int(C.SDL_GetNumRenderDrivers()) 59 | } 60 | 61 | type RendererInfo struct { 62 | name *byte 63 | flags uint32 64 | mod_modes uint32 65 | blend_modes uint32 66 | scale_modes uint32 67 | num_texture_formats uint32 68 | texture_formats [50]uint32 69 | max_texture_width int32 70 | max_texture_height int32 71 | } 72 | 73 | func GetRenderDriverInfo(_index int) *RendererInfo { 74 | var rendererInfo *RendererInfo = &RendererInfo{} 75 | C.SDL_GetRenderDriverInfo(C.int(_index), (*C.SDL_RendererInfo)(cast(rendererInfo))); 76 | return rendererInfo 77 | } 78 | 79 | func GetRenderDriverName(_index int) string { 80 | info := GetRenderDriverInfo(_index) 81 | strname := "" 82 | for c := 0;; c++ { 83 | var name = uintptr(unsafe.Pointer(info.name))+uintptr(c) 84 | ch := (*uint8)(cast(name)) 85 | if *ch == uint8(0) { 86 | break 87 | } 88 | strname += string(*ch) 89 | } 90 | return strname 91 | } 92 | 93 | type Renderer C.SDL_Renderer 94 | 95 | func (r *Renderer) Get() *C.SDL_Renderer { 96 | return (*C.SDL_Renderer)(cast(r)) 97 | } 98 | 99 | func (r *Renderer) Release() { 100 | C.SDL_DestroyRenderer(r.Get()) 101 | } 102 | 103 | func CreateRenderer(_window *Window, _index int) (renderer *Renderer, error string) { 104 | raw := C.SDL_CreateRenderer(_window.window, C.int(_index), C.SDL_RENDERER_PRESENTVSYNC | C.SDL_RENDERER_ACCELERATED) 105 | if raw == nil { 106 | error = GetError() 107 | return 108 | } 109 | renderer = (*Renderer)(cast(raw)) 110 | return 111 | } 112 | 113 | func RenderClear(_renderer *Renderer) { 114 | C.SDL_RenderClear(_renderer.Get()) 115 | } 116 | 117 | func RenderPresent(_renderer *Renderer) { 118 | C.SDL_RenderPresent(_renderer.Get()) 119 | } 120 | 121 | func RenderFillRect(_renderer *Renderer, _rect Rect) { 122 | C.SDL_RenderFillRect(_renderer.Get(), (*C.SDL_Rect)(cast(&_rect))) 123 | } 124 | 125 | func RenderDrawRect(_renderer *Renderer, _rect Rect) { 126 | C.SDL_RenderDrawRect(_renderer.Get(), (*C.SDL_Rect)(cast(&_rect))) 127 | } 128 | 129 | func RenderDrawLine(_renderer *Renderer, _x1, _y1, _x2, _y2 int) { 130 | C.SDL_RenderDrawLine(_renderer.Get(), C.int(_x1), C.int(_y1), C.int(_x2), C.int(_y2)) 131 | } 132 | 133 | func SetRenderDrawColor(_renderer *Renderer, _r uint8, _g uint8, _b uint8, _a uint8) { 134 | C.SDL_SetRenderDrawColor(_renderer.Get(), C.Uint8(_r), C.Uint8(_g), C.Uint8(_b), C.Uint8(_a)) 135 | } 136 | 137 | func SetRenderDrawBlendMode(_renderer *Renderer, _mode int) { 138 | C.SDL_SetRenderDrawBlendMode(_renderer.Get(), C.SDL_BlendMode(_mode)) 139 | } 140 | -------------------------------------------------------------------------------- /sdl/sdl.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | //#include "SDL.h" 4 | import "C" 5 | import "unsafe" 6 | 7 | type cast unsafe.Pointer 8 | 9 | func Delay(_ticks uint32) { 10 | C.SDL_Delay(C.Uint32(_ticks)) 11 | } 12 | 13 | func GetTicks() uint32 { 14 | return uint32(C.SDL_GetTicks()) 15 | } 16 | 17 | func Quit() { 18 | C.SDL_Quit() 19 | } 20 | 21 | func GetError() (ret string) { 22 | ret = C.GoString(C.SDL_GetError()) 23 | C.SDL_ClearError() 24 | return 25 | } 26 | 27 | func KeyDown(_key int) bool { 28 | zero := C.int(0) 29 | var state = uintptr(unsafe.Pointer(C.SDL_GetKeyboardState(&zero)))+uintptr(_key) 30 | down := (*uint8)(cast(state)) 31 | if *down == 1 { 32 | return true 33 | } 34 | return false 35 | } 36 | 37 | func Init() (error string) { 38 | flags := int64(C.SDL_INIT_VIDEO) 39 | if C.SDL_Init(C.Uint32(flags)) != 0 { 40 | error = C.GoString(C.SDL_GetError()) 41 | return 42 | } 43 | return "" 44 | } 45 | 46 | type Window struct { 47 | window *C.SDL_Window 48 | } 49 | 50 | func CreateWindow(_title string, _width int, _height int) (*Window, string) { 51 | ctitle := C.CString(_title) 52 | var window *C.SDL_Window = C.SDL_CreateWindow(ctitle, 53 | C.SDL_WINDOWPOS_CENTERED, 54 | C.SDL_WINDOWPOS_CENTERED, 55 | C.int(_width), 56 | C.int(_height), 57 | C.SDL_WINDOW_SHOWN | C.SDL_WINDOW_OPENGL) 58 | C.free(unsafe.Pointer(ctitle)) 59 | if window == nil { 60 | return nil, GetError() 61 | } 62 | return &Window{window}, "" 63 | } 64 | 65 | func DestroyWindow(_window *Window) { 66 | C.SDL_DestroyWindow(_window.window) 67 | } 68 | 69 | func PollEvent() (*SDLEvent, bool) { 70 | var ev *SDLEvent = &SDLEvent{} 71 | if C.SDL_PollEvent((*C.SDL_Event)(cast(ev))) != 0 { 72 | return ev, true 73 | } 74 | return nil, false 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /sdl/ttf.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | //#include "SDL_ttf.h" 4 | import "C" 5 | import "unsafe" 6 | 7 | func InitTTF() int { 8 | return int(C.TTF_Init()) 9 | } 10 | 11 | func QuitTTF() { 12 | C.TTF_Quit(); 13 | } 14 | 15 | type Font C.TTF_Font 16 | 17 | func LoadFont(_file string, _size int) *Font { 18 | cfile := C.CString(_file); defer C.free(unsafe.Pointer(cfile)) 19 | font := C.TTF_OpenFont(cfile, C.int(_size)) 20 | if font == nil { 21 | return nil 22 | } 23 | return (*Font)(cast(font)) 24 | } 25 | 26 | func (f *Font) Get() *C.TTF_Font { 27 | return (*C.TTF_Font)(cast(f)) 28 | } 29 | 30 | func (f *Font) Release() { 31 | C.TTF_CloseFont(f.Get()) 32 | } 33 | 34 | func (f *Font) RenderText_Blended(_text string, color Color) *Surface { 35 | ccolor := (*C.SDL_Color)(cast(&color)) 36 | ctext := C.CString(_text); defer C.free(unsafe.Pointer(ctext)) 37 | sf := C.TTF_RenderText_Blended(f.Get(), ctext, *ccolor) 38 | return (*Surface)(cast(sf)) 39 | } 40 | 41 | func (f *Font) GetHeight() int { 42 | return int(C.TTF_FontHeight(f.Get())) 43 | } 44 | 45 | func (f *Font) GetMetrics(_ch uint16) (int,int,int,int,int) { 46 | var minx, maxx, miny, maxy, advance C.int 47 | C.TTF_GlyphMetrics(f.Get(), C.Uint16(_ch), (*C.int)(cast(&minx)), (*C.int)(cast(&maxx)), (*C.int)(cast(&miny)), (*C.int)(cast(&maxy)), (*C.int)(cast(&advance))); 48 | return int(minx), int(maxx), int(miny), int(maxy), int(advance) 49 | } 50 | 51 | func (f *Font) GetKerning(_previous int, _current int) int { 52 | return int(C.TTF_GetFontKerningSize(f.Get(),C.int(_previous), C.int(_current))) 53 | } 54 | 55 | func (f *Font) SetStyle(_bold bool, _italic bool, _underline bool) { 56 | var flags int 57 | 58 | if(_bold) { 59 | flags |= C.TTF_STYLE_BOLD; 60 | } 61 | if(_italic) { 62 | flags |= C.TTF_STYLE_ITALIC; 63 | } 64 | if(_underline) { 65 | flags |= C.TTF_STYLE_UNDERLINE; 66 | } 67 | 68 | if(flags == 0) { 69 | flags = C.TTF_STYLE_NORMAL; 70 | } 71 | 72 | C.TTF_SetFontStyle(f.Get(), C.int(flags)); 73 | } 74 | -------------------------------------------------------------------------------- /skeleton/Makefile: -------------------------------------------------------------------------------- 1 | include $(GOROOT)/src/Make.inc 2 | 3 | TARG=skeleton 4 | GOFILES=\ 5 | *.go\ 6 | 7 | include $(GOROOT)/src/Make.cmd 8 | -------------------------------------------------------------------------------- /skeleton/skeleton.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "go2d" 4 | 5 | func start() { 6 | //load resources here 7 | } 8 | 9 | func update(dt uint32) { 10 | //game mechanics here 11 | //this is called every frame before the draw function 12 | } 13 | 14 | func draw() { 15 | //rendering here 16 | //this is called every frame 17 | } 18 | 19 | func mouseMove(x, y int16) { 20 | //mouse move events 21 | } 22 | 23 | func mouseUp(x, y int16) { 24 | //mouse up events 25 | } 26 | 27 | func mouseDown(x, y int16) { 28 | //mouse down events 29 | } 30 | 31 | func textInput(char uint8) { 32 | //text input events 33 | } 34 | 35 | func keyDown(key int) { 36 | //key down events 37 | } 38 | 39 | func main() { 40 | game := go2d.NewGame("Skeleton") 41 | game.SetDimensions(200, 200) 42 | 43 | //Set to false when OpenGL should also be defaulted on Windows 44 | game.SetD3D(true) 45 | 46 | game.SetInitFun(start) 47 | game.SetUpdateFun(update) 48 | game.SetDrawFun(draw) 49 | 50 | game.SetMouseMoveFun(mouseMove) 51 | game.SetMouseDownFun(mouseDown) 52 | game.SetMouseUpFun(mouseUp) 53 | game.SetTextInputFun(textInput) 54 | game.SetKeyDownFun(keyDown) 55 | 56 | game.Run() 57 | } -------------------------------------------------------------------------------- /test/basic/Makefile: -------------------------------------------------------------------------------- 1 | include $(GOROOT)/src/Make.inc 2 | 3 | TARG=test 4 | GOFILES=\ 5 | *.go\ 6 | 7 | include $(GOROOT)/src/Make.cmd 8 | -------------------------------------------------------------------------------- /test/basic/arial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PikeDev/Go2D/0e8a27a19b89ed437b17cbc8f8f2b74bff56e4f4/test/basic/arial.ttf -------------------------------------------------------------------------------- /test/basic/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "go2d" 5 | "fmt" 6 | ) 7 | 8 | var image *go2d.Image 9 | var arial16 *go2d.Font 10 | 11 | func start() { 12 | image = go2d.NewImage("test.png") 13 | 14 | arial16 = go2d.NewFont("arial.ttf", 16) 15 | arial16.SetStyle(true, false, false) 16 | arial16.SetColor(255, 255, 255) 17 | } 18 | 19 | func update(dt uint32) { 20 | //game mechanics here 21 | } 22 | 23 | func draw() { 24 | image.DrawRect(go2d.NewRect(10, 10, 100, 100)) 25 | 26 | image.Draw(10, 200) 27 | 28 | arial16.DrawText("Testing...", 200, 10) 29 | 30 | go2d.DrawFillRect(go2d.NewRect(350, 200, 100, 100), 255, 100, 0, 255) 31 | } 32 | 33 | func mouseUp(x, y int16) { 34 | fmt.Printf("Mouse up x: %d y: %d\n", x, y) 35 | } 36 | 37 | func textInput(char uint8) { 38 | fmt.Printf("Text input: %c\n", char) 39 | } 40 | 41 | func keyDown(key int) { 42 | switch key { 43 | case go2d.KEY_UP: 44 | fmt.Println("Going up") 45 | case go2d.KEY_DOWN: 46 | fmt.Println("Going down") 47 | } 48 | } 49 | 50 | func main() { 51 | game := go2d.NewGame("Test Game") 52 | game.SetDimensions(800, 600) 53 | game.SetD3D(true) 54 | 55 | game.SetInitFun(start) 56 | game.SetUpdateFun(update) 57 | game.SetDrawFun(draw) 58 | 59 | game.SetMouseUpFun(mouseUp) 60 | game.SetTextInputFun(textInput) 61 | game.SetKeyDownFun(keyDown) 62 | 63 | game.Run() 64 | } -------------------------------------------------------------------------------- /test/basic/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PikeDev/Go2D/0e8a27a19b89ed437b17cbc8f8f2b74bff56e4f4/test/basic/test.png -------------------------------------------------------------------------------- /test/gui/Makefile: -------------------------------------------------------------------------------- 1 | include $(GOROOT)/src/Make.inc 2 | 3 | TARG=test_gui 4 | GOFILES=\ 5 | *.go\ 6 | 7 | include $(GOROOT)/src/Make.cmd 8 | -------------------------------------------------------------------------------- /test/gui/arial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PikeDev/Go2D/0e8a27a19b89ed437b17cbc8f8f2b74bff56e4f4/test/gui/arial.ttf -------------------------------------------------------------------------------- /test/gui/button_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PikeDev/Go2D/0e8a27a19b89ed437b17cbc8f8f2b74bff56e4f4/test/gui/button_down.png -------------------------------------------------------------------------------- /test/gui/button_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PikeDev/Go2D/0e8a27a19b89ed437b17cbc8f8f2b74bff56e4f4/test/gui/button_hover.png -------------------------------------------------------------------------------- /test/gui/button_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PikeDev/Go2D/0e8a27a19b89ed437b17cbc8f8f2b74bff56e4f4/test/gui/button_normal.png -------------------------------------------------------------------------------- /test/gui/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "go2d" 5 | "fmt" 6 | ) 7 | 8 | //Constants 9 | const ( 10 | WINDOW_WIDTH = 800 11 | WINDOW_HEIGHT = 600 12 | ) 13 | 14 | //Globals 15 | var ( 16 | g_game *go2d.Game 17 | g_window *go2d.Window 18 | ) 19 | 20 | func start() { 21 | //Load up our default font for GUI text elements 22 | arial := go2d.NewFont("arial.ttf", 14) 23 | arial.SetStyle(true, false, false) 24 | arial.SetColor(255, 255, 255) 25 | 26 | //Initialize the GUI system (use whole window area) 27 | g_window = g_game.InitGUI(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, arial) 28 | 29 | //Set up some elements 30 | 31 | //A panel 32 | panel := go2d.NewPanel(20, 20, 200, 200) 33 | panel.SetBackgroundColor(80, 80, 255) 34 | 35 | //Another panel in the panel that gets clipped 36 | innerPanel := go2d.NewPanel(180, 180, 50,50) 37 | innerPanel.SetBackgroundColor(255, 80, 80) 38 | panel.AddChild(innerPanel) 39 | 40 | //A label 41 | label := go2d.NewLabel(10, 10, "This is a test label") 42 | panel.AddChild(label) 43 | 44 | //A button 45 | button := go2d.NewButton(10, 40, 100, 30, "Click here") 46 | button.SetFontColor(80, 80, 80) 47 | button.SetBackgroundColor(80, 255, 80) 48 | button.SetOnClickListener(func(x, y int) { 49 | println("Button clicked!") 50 | }) 51 | panel.AddChild(button) 52 | 53 | //A textfield 54 | textfield := go2d.NewTextField(10, 80, 150, 30) 55 | textfield.SetFontColor(0, 0, 0) 56 | textfield.SetBackgroundColor(255, 255, 255) 57 | textfield.SetBorderColor(0, 0, 0) 58 | panel.AddChild(textfield) 59 | 60 | //A password textfield 61 | password := go2d.NewTextField(10, 120, 150, 30) 62 | password.SetPassword(true) 63 | password.SetFontColor(0, 0, 0) 64 | password.SetBackgroundColor(255, 255, 255) 65 | password.SetBorderColor(0, 0, 0) 66 | panel.AddChild(password) 67 | 68 | g_window.AddChild(panel) 69 | 70 | //A customized button 71 | customButton := go2d.NewButton(20, 240, 186, 52, "") 72 | customButton.SetImage(go2d.NewImage("button_normal.png")) 73 | customButton.SetHoverImage(go2d.NewImage("button_hover.png")) 74 | customButton.SetMouseDownImage(go2d.NewImage("button_down.png")) 75 | customButton.SetOnClickListener(CustomButtonOnClick) 76 | g_window.AddChild(customButton) 77 | 78 | //A scrollbar 79 | scrollBar := go2d.NewScrollbar(300, 20, 20, 140, go2d.SCROLLBAR_VERTICAL) 80 | scrollBar.SetOnValueChangeListener(func(value int) { 81 | fmt.Printf("Scrollbar value: %d\n", value) 82 | }) 83 | g_window.AddChild(scrollBar) 84 | } 85 | 86 | func CustomButtonOnClick(x, y int) { 87 | println("Custom button clicked!") 88 | } 89 | 90 | func update(dt uint32) { 91 | //game mechanics here 92 | } 93 | 94 | func draw() { 95 | 96 | } 97 | 98 | func main() { 99 | g_game = go2d.NewGame("Test Game") 100 | g_game.SetDimensions(WINDOW_WIDTH, WINDOW_HEIGHT) 101 | g_game.SetD3D(true) 102 | 103 | g_game.SetInitFun(start) 104 | g_game.SetUpdateFun(update) 105 | g_game.SetDrawFun(draw) 106 | 107 | g_game.Run() 108 | } --------------------------------------------------------------------------------