commit 1c170e23f8a96b472c3133a14662dfa2709e02ec Author: Lilis Iskandar Date: Thu Jan 18 09:51:32 2018 +0800 Initial commit Signed-off-by: Lilis Iskandar diff --git a/assets/test.bmp b/assets/test.bmp new file mode 100644 index 0000000..723e0ab Binary files /dev/null and b/assets/test.bmp differ diff --git a/assets/test.mp3 b/assets/test.mp3 new file mode 100644 index 0000000..bc34e6c Binary files /dev/null and b/assets/test.mp3 differ diff --git a/assets/test.png b/assets/test.png new file mode 100644 index 0000000..d7f535b Binary files /dev/null and b/assets/test.png differ diff --git a/assets/test.ttf b/assets/test.ttf new file mode 100644 index 0000000..5267218 Binary files /dev/null and b/assets/test.ttf differ diff --git a/assets/test.wav b/assets/test.wav new file mode 100644 index 0000000..aaf45c9 Binary files /dev/null and b/assets/test.wav differ diff --git a/examples/audio/audio.go b/examples/audio/audio.go new file mode 100644 index 0000000..fe72e3a --- /dev/null +++ b/examples/audio/audio.go @@ -0,0 +1,57 @@ +package main + +// typedef unsigned char Uint8; +// void SineWave(void *userdata, Uint8 *stream, int len); +import "C" +import ( + "log" + "math" + "reflect" + "unsafe" + + "github.com/veandco/go-sdl2/sdl" +) + +const ( + toneHz = 440 + sampleHz = 48000 + dPhase = 2 * math.Pi * toneHz / sampleHz +) + +//export SineWave +func SineWave(userdata unsafe.Pointer, stream *C.Uint8, length C.int) { + n := int(length) + hdr := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(stream)), Len: n, Cap: n} + buf := *(*[]C.Uint8)(unsafe.Pointer(&hdr)) + + var phase float64 + for i := 0; i < n; i += 2 { + phase += dPhase + sample := C.Uint8((math.Sin(phase) + 0.999999) * 128) + buf[i] = sample + buf[i+1] = sample + } +} + +func main() { + if err := sdl.Init(sdl.INIT_AUDIO); err != nil { + log.Println(err) + return + } + defer sdl.Quit() + + spec := &sdl.AudioSpec{ + Freq: sampleHz, + Format: sdl.AUDIO_U8, + Channels: 2, + Samples: sampleHz, + Callback: sdl.AudioCallback(C.SineWave), + } + if err := sdl.OpenAudio(spec, nil); err != nil { + log.Println(err) + return + } + sdl.PauseAudio(false) + sdl.Delay(5000) // play audio for long enough to understand whether it works + sdl.CloseAudio() +} diff --git a/examples/audio_mp3/audio_mp3.c b/examples/audio_mp3/audio_mp3.c new file mode 100644 index 0000000..487e870 --- /dev/null +++ b/examples/audio_mp3/audio_mp3.c @@ -0,0 +1,45 @@ +#include +#include + +int main() +{ + Mix_Music *music = 0; + int ret = 0; + + ret = SDL_Init(SDL_INIT_AUDIO); + if (ret) { + fprintf(stderr, "%s\n", SDL_GetError()); + return 1; + } + + ret = Mix_Init(MIX_INIT_MP3); + if ((ret & MIX_INIT_MP3) != MIX_INIT_MP3) { + fprintf(stderr, "%s\n", SDL_GetError()); + return 2; + } + + ret = Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096); + if (ret < 0) { + fprintf(stderr, "%s\n", SDL_GetError()); + return 3; + } + + music = Mix_LoadMUS("../../assets/test.mp3"); + if (!music) { + fprintf(stderr, "%s\n", SDL_GetError()); + return 4; + } + + ret = Mix_PlayMusic(music, 1); + if (ret == -1) { + fprintf(stderr, "%s\n", SDL_GetError()); + return 5; + } + + SDL_Delay(5000); + + Mix_FreeMusic(music); + Mix_CloseAudio(); + Mix_Quit(); + SDL_Quit(); +} diff --git a/examples/audio_mp3/audio_mp3.go b/examples/audio_mp3/audio_mp3.go new file mode 100644 index 0000000..9bfa1f6 --- /dev/null +++ b/examples/audio_mp3/audio_mp3.go @@ -0,0 +1,37 @@ +package main + +import ( + "log" + + "github.com/veandco/go-sdl2/sdl" + "github.com/veandco/go-sdl2/mix" +) + +func main() { + if err := sdl.Init(sdl.INIT_AUDIO); err != nil { + log.Println(err) + return + } + defer sdl.Quit() + + if err := mix.Init(mix.INIT_MP3); err != nil { + log.Println(err) + return + } + defer mix.Quit() + + if err := mix.OpenAudio(22050, mix.DEFAULT_FORMAT, 2, 4096); err != nil { + log.Println(err) + return + } + defer mix.CloseAudio() + + if music, err := mix.LoadMUS("../../assets/test.mp3"); err != nil { + log.Println(err) + } else if err = music.Play(1); err != nil { + log.Println(err) + } else { + sdl.Delay(5000) + music.Free() + } +} diff --git a/examples/audio_wav_memory/audio_wav_memory.go b/examples/audio_wav_memory/audio_wav_memory.go new file mode 100644 index 0000000..499bfce --- /dev/null +++ b/examples/audio_wav_memory/audio_wav_memory.go @@ -0,0 +1,45 @@ +package main + +import ( + "io/ioutil" + "log" + + "github.com/veandco/go-sdl2/sdl" + "github.com/veandco/go-sdl2/mix" +) + +func main() { + if err := sdl.Init(sdl.INIT_AUDIO); err != nil { + log.Println(err) + return + } + defer sdl.Quit() + + if err := mix.OpenAudio(44100, mix.DEFAULT_FORMAT, 2, 4096); err != nil { + log.Println(err) + return + } + defer mix.CloseAudio() + + // Load entire WAV data from file + data, err := ioutil.ReadFile("../../assets/test.wav") + if err != nil { + log.Println(err) + } + + // Load WAV from data (memory) + chunk, err := mix.QuickLoadWAV(data) + if err != nil { + log.Println(err) + } + defer chunk.Free() + + // Play 4 times + chunk.Play(1, 3) + + // Wait until it finishes playing + for mix.Playing(-1) == 1 { + sdl.Delay(16) + } +} + diff --git a/examples/events/PeepEvents_add.go b/examples/events/PeepEvents_add.go new file mode 100644 index 0000000..45b132c --- /dev/null +++ b/examples/events/PeepEvents_add.go @@ -0,0 +1,87 @@ +// This program creates an SDL window and renderer and pushes UserEvents using PeepEvents +package main + +import ( + "fmt" + "github.com/veandco/go-sdl2/sdl" + "os" +) + +var winTitle string = "Go-SDL2 TestWaitEvent" +var winWidth, winHeight int = 800, 600 + +const pushTime uint32 = 1000 // number of milliseconds between event pushes + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var event sdl.Event + var running bool + var err error + + sdl.Init(sdl.INIT_EVERYTHING) + defer sdl.Quit() + + window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_SHOWN) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer window.Destroy() + + renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err) + return 2 + } + defer renderer.Destroy() + + var peepArray []sdl.Event = make([]sdl.Event, 2) + peepArray[0] = &sdl.UserEvent{sdl.USEREVENT, sdl.GetTicks(), window.GetID(), 1331, nil, nil} + peepArray[1] = &sdl.UserEvent{sdl.USEREVENT, sdl.GetTicks(), window.GetID(), 10101, nil, nil} + + running = true + lastPushTime := sdl.GetTicks() + for running { + if lastPushTime+pushTime < sdl.GetTicks() { + lastPushTime = sdl.GetTicks() + sdl.PumpEvents() + numEventsHandled, err := sdl.PeepEvents(peepArray, sdl.ADDEVENT, sdl.FIRSTEVENT, sdl.LASTEVENT) + if err != nil { + fmt.Fprintf(os.Stderr, "PeepEvents error: %s\n", err) + return 3 + } else { + fmt.Printf("Successful push of %d events\n", numEventsHandled) + } + } + + for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() { + switch t := event.(type) { + case *sdl.QuitEvent: + running = false + case *sdl.MouseMotionEvent: + fmt.Printf("[%d ms] MouseMotion\ttype:%d\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel) + case *sdl.MouseButtonEvent: + fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State) + case *sdl.MouseWheelEvent: + fmt.Printf("[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y) + case *sdl.KeyUpEvent: + fmt.Printf("[%d ms] Keyboard\ttype:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n", + t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat) + case *sdl.UserEvent: + fmt.Printf("[%d ms] UserEvent\tcode:%d\n", t.Timestamp, t.Code) + } + } + sdl.Delay(1000 / 30) + } + + return 0 +} + +func main() { + os.Exit(run()) +} diff --git a/examples/events/PeepEvents_peek.go b/examples/events/PeepEvents_peek.go new file mode 100644 index 0000000..4c93bd9 --- /dev/null +++ b/examples/events/PeepEvents_peek.go @@ -0,0 +1,79 @@ +// This program creates an SDL window and renderer and takes in events using sdl.PeepEvents +package main + +import ( + "fmt" + "github.com/veandco/go-sdl2/sdl" + "os" +) + +var winTitle string = "Go-SDL2 TestWaitEvent" +var winWidth, winHeight int = 800, 600 + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var event sdl.Event + var running bool + var err error + + sdl.Init(sdl.INIT_EVERYTHING) + defer sdl.Quit() + + window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_SHOWN) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer window.Destroy() + + renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err) + return 2 + } + defer renderer.Destroy() + + var peepArray []sdl.Event = make([]sdl.Event, 5) + + running = true + for running { + sdl.PumpEvents() + numEventsRetrieved, err := sdl.PeepEvents(peepArray, sdl.PEEKEVENT, sdl.FIRSTEVENT, sdl.LASTEVENT) + if err != nil { + fmt.Fprintf(os.Stderr, "PeepEvents error: %s\n", err) + return 3 + } else { + for i := 0; i < numEventsRetrieved; i++ { + fmt.Printf("Event Peeked Value: %v\n", peepArray[i]) // primitive printing of event + } + } + + for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() { + switch t := event.(type) { + case *sdl.QuitEvent: + running = false + case *sdl.MouseMotionEvent: + fmt.Printf("[%d ms] MouseMotion\ttype:%d\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel) + case *sdl.MouseButtonEvent: + fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State) + case *sdl.MouseWheelEvent: + fmt.Printf("[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y) + case *sdl.KeyUpEvent: + fmt.Printf("[%d ms] Keyboard\ttype:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n", + t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat) + } + } + sdl.Delay(1000 / 30) + } + + return 0 +} + +func main() { + os.Exit(run()) +} \ No newline at end of file diff --git a/examples/events/PushEvent.go b/examples/events/PushEvent.go new file mode 100644 index 0000000..ca7cdcb --- /dev/null +++ b/examples/events/PushEvent.go @@ -0,0 +1,90 @@ +// This program creates an SDL window and renderer and pushes events with PushEvent to be read by PollEvents +package main + +import ( + "fmt" + "github.com/veandco/go-sdl2/sdl" + "os" +) + +var winTitle string = "Go-SDL2 TestWaitEvent" +var winWidth, winHeight int = 800, 600 + +const pushTime uint32 = 1000 // number of milliseconds between event pushes + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var event sdl.Event + var running bool + var err error + + sdl.Init(sdl.INIT_EVERYTHING) + defer sdl.Quit() + + window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_SHOWN) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer window.Destroy() + + renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err) + return 2 + } + defer renderer.Destroy() + + running = true + lastPushTime := sdl.GetTicks() + for running { + + // Push a UserEvent every second + if lastPushTime+pushTime < sdl.GetTicks() { + lastPushTime = sdl.GetTicks() + pEvent := &sdl.UserEvent{sdl.USEREVENT, sdl.GetTicks(), window.GetID(), 1331, nil, nil} + + retVal, err := sdl.PushEvent(pEvent) // Here's where the event is actually pushed + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to push event: %s\n", err) + return 3 + } + + if retVal { + fmt.Println("PushEvent returned success") + } else { + fmt.Println("PushEvent returned filtered") + } + } + + for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() { + switch t := event.(type) { + case *sdl.QuitEvent: + running = false + case *sdl.MouseMotionEvent: + fmt.Printf("[%d ms] MouseMotion\ttype:%d\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel) + case *sdl.MouseButtonEvent: + fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State) + case *sdl.MouseWheelEvent: + fmt.Printf("[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y) + case *sdl.KeyUpEvent: + fmt.Printf("[%d ms] Keyboard\ttype:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n", + t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat) + case *sdl.UserEvent: + fmt.Printf("[%d ms] UserEvent\tcode:%d\n", t.Timestamp, t.Code) + } + } + sdl.Delay(1000 / 30) + } + + return 0 +} + +func main() { + os.Exit(run()) +} diff --git a/examples/events/WaitEvent.go b/examples/events/WaitEvent.go new file mode 100644 index 0000000..0a88c57 --- /dev/null +++ b/examples/events/WaitEvent.go @@ -0,0 +1,64 @@ +// This program creates an SDL window and renderer and takes in events using sdl.WaitEvent +package main + +import ( + "fmt" + "github.com/veandco/go-sdl2/sdl" + "os" +) + +var winTitle string = "Go-SDL2 TestWaitEvent" +var winWidth, winHeight int = 800, 600 + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var event sdl.Event + var running bool + var err error + + sdl.Init(sdl.INIT_EVERYTHING) + defer sdl.Quit() + + window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_SHOWN) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer window.Destroy() + + renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err) + return 2 + } + defer renderer.Destroy() + + running = true + for running { + event = sdl.WaitEvent() // wait here until an event is in the event queue + switch t := event.(type) { + case *sdl.QuitEvent: + running = false + case *sdl.MouseMotionEvent: + fmt.Printf("[%d ms] MouseMotion\ttype:%d\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel) + case *sdl.MouseButtonEvent: + fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State) + case *sdl.MouseWheelEvent: + fmt.Printf("[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y) + case *sdl.KeyUpEvent: + fmt.Printf("[%d ms] Keyboard\ttype:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n", + t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat) + } + } + + return 0 +} + +func main() { + os.Exit(run()) +} diff --git a/examples/events/WaitEventTimeout.go b/examples/events/WaitEventTimeout.go new file mode 100644 index 0000000..73188ac --- /dev/null +++ b/examples/events/WaitEventTimeout.go @@ -0,0 +1,70 @@ +// This program creates an SDL window and renderer and takes in events using sdl.WaitEventTimeout +// If there is a timeout (1000 ms), the program prints that there was and tries again +package main + +import ( + "fmt" + "github.com/veandco/go-sdl2/sdl" + "os" +) + +var winTitle string = "Go-SDL2 TestWaitEvent" +var winWidth, winHeight int = 800, 600 + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var event sdl.Event + var running bool + var err error + + sdl.Init(sdl.INIT_EVERYTHING) + defer sdl.Quit() + + window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_SHOWN) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer window.Destroy() + + renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err) + return 2 + } + defer renderer.Destroy() + + running = true + for running { + event = sdl.WaitEventTimeout(1000) // wait here until an event is in the event queue + if event == nil { + fmt.Println("WaitEventTimeout timed out") + continue + } + + switch t := event.(type) { + case *sdl.QuitEvent: + running = false + case *sdl.MouseMotionEvent: + fmt.Printf("[%d ms] MouseMotion\ttype:%d\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel) + case *sdl.MouseButtonEvent: + fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State) + case *sdl.MouseWheelEvent: + fmt.Printf("[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y) + case *sdl.KeyUpEvent: + fmt.Printf("[%d ms] Keyboard\ttype:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n", + t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat) + } + } + + return 0 +} + +func main() { + os.Exit(run()) +} diff --git a/examples/events/events.c b/examples/events/events.c new file mode 100644 index 0000000..af40932 --- /dev/null +++ b/examples/events/events.c @@ -0,0 +1,89 @@ +// author: Jacky Boen + +#include + +static const char *window_title = "SDL2 Events"; +static const int window_width = 800, window_height = 600; +static SDL_Joystick *joysticks[16]; + +int main() { + SDL_Window *window; + SDL_bool running = SDL_TRUE; + + SDL_Init(SDL_INIT_EVERYTHING); + + window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_width, window_height, SDL_WINDOW_SHOWN); + if (!window) { + fprintf(stderr, "%s\n", SDL_GetError()); + return -1; + } + + SDL_JoystickEventState(SDL_ENABLE); + + while (running) { + SDL_Event event; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + running = SDL_FALSE; + break; + case SDL_MOUSEMOTION: + fprintf(stdout, "[%d ms] MouseMotion\ttype:%d\twhich:\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", + event.motion.timestamp, event.motion.type, event.motion.which, event.motion.x, event.motion.y, event.motion.xrel, event.motion.yrel); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + fprintf(stdout, "[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n", + event.button.timestamp, event.button.type, event.button.which, event.button.x, event.button.y, event.button.button, event.button.state); + break; + case SDL_MOUSEWHEEL: + fprintf(stdout, "[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n", + event.wheel.timestamp, event.wheel.type, event.wheel.which, event.wheel.x, event.wheel.y); + break; + case SDL_KEYDOWN: + case SDL_KEYUP: + fprintf(stdout, "[%d ms] Keyboard\ttype:%d\twindowID:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n", + event.key.timestamp, event.key.type, event.key.windowID, event.key.keysym.sym, event.key.keysym.mod, event.key.state, event.key.repeat); + break; + case SDL_JOYAXISMOTION: + fprintf(stdout, "[%d ms] JoyAxis\ttype:%d\twhich:%d\taxis:%d\tvalue:%d\n", + event.jaxis.timestamp, event.jaxis.type, event.jaxis.which, event.jaxis.axis, event.jaxis.value); + break; + case SDL_JOYBALLMOTION: + fprintf(stdout, "[%d ms] JoyBall\ttype:%d\twhich:%d\tball:%d\txrel:%d\tyrel:%d\n", + event.jball.timestamp, event.jball.type, event.jball.which, event.jball.ball, event.jball.xrel, event.jball.yrel); + break; + case SDL_JOYBUTTONUP: + case SDL_JOYBUTTONDOWN: + fprintf(stdout, "[%d ms] JoyButton\ttype:%d\twhich:%d\tbutton:%d\tstate:%d\n", + event.jbutton.timestamp, event.jbutton.type, event.jbutton.which, event.jbutton.button, event.jbutton.state); + break; + case SDL_JOYHATMOTION: + fprintf(stdout, "[%d ms] JoyHat\ttype:%d\twhich:%d\that:%d\tvalue:%d\n", + event.jhat.timestamp, event.jhat.type, event.jhat.which, event.jhat.hat, event.jhat.value); + break; + case SDL_JOYDEVICEADDED: + joysticks[event.jdevice.which] = SDL_JoystickOpen(event.jdevice.which); + if (joysticks[event.jdevice.which]) { + fprintf(stdout, "Joystick %d connected\n", event.jdevice.which); + } + break; + case SDL_JOYDEVICEREMOVED: + if (!joysticks[event.jdevice.which]) { + SDL_JoystickClose(joysticks[event.jdevice.which]); + } + fprintf(stdout, "Joystick %d disconnected\n", event.jdevice.which); + break; + default: + fprintf(stdout, "Some event\n"); + break; + } + } + } + + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/examples/events/events.go b/examples/events/events.go new file mode 100644 index 0000000..76d7202 --- /dev/null +++ b/examples/events/events.go @@ -0,0 +1,89 @@ +// author: Jacky Boen + +package main + +import ( + "fmt" + "github.com/veandco/go-sdl2/sdl" + "os" +) + +var winTitle string = "Go-SDL2 Events" +var winWidth, winHeight int32 = 800, 600 +var joysticks [16]*sdl.Joystick + +func run() int { + var window *sdl.Window + var event sdl.Event + var running bool + var err error + + sdl.Init(sdl.INIT_EVERYTHING) + defer sdl.Quit() + + window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_SHOWN) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer window.Destroy() + + sdl.JoystickEventState(sdl.ENABLE) + + running = true + for running { + for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() { + switch t := event.(type) { + case *sdl.QuitEvent: + running = false + case *sdl.MouseMotionEvent: + fmt.Printf("[%d ms] MouseMotion\ttype:%d\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel) + case *sdl.MouseButtonEvent: + fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State) + case *sdl.MouseWheelEvent: + fmt.Printf("[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y) + case *sdl.KeyboardEvent: + fmt.Printf("[%d ms] Keyboard\ttype:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n", + t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat) + case *sdl.JoyAxisEvent: + fmt.Printf("[%d ms] JoyAxis\ttype:%d\twhich:%c\taxis:%d\tvalue:%d\n", + t.Timestamp, t.Type, t.Which, t.Axis, t.Value) + case *sdl.JoyBallEvent: + fmt.Printf("[%d ms] JoyBall\ttype:%d\twhich:%d\tball:%d\txrel:%d\tyrel:%d\n", + t.Timestamp, t.Type, t.Which, t.Ball, t.XRel, t.YRel) + case *sdl.JoyButtonEvent: + fmt.Printf("[%d ms] JoyButton\ttype:%d\twhich:%d\tbutton:%d\tstate:%d\n", + t.Timestamp, t.Type, t.Which, t.Button, t.State) + case *sdl.JoyHatEvent: + fmt.Printf("[%d ms] JoyHat\ttype:%d\twhich:%d\that:%d\tvalue:%d\n", + t.Timestamp, t.Type, t.Which, t.Hat, t.Value) + case *sdl.JoyDeviceEvent: + if t.Type == sdl.JOYDEVICEADDED { + joysticks[int(t.Which)] = sdl.JoystickOpen(t.Which) + if joysticks[int(t.Which)] != nil { + fmt.Printf("Joystick %d connected\n", t.Which) + } + } else if t.Type == sdl.JOYDEVICEREMOVED { + if joystick := joysticks[int(t.Which)]; joystick != nil { + joystick.Close() + } + fmt.Printf("Joystick %d disconnected\n", t.Which) + } + default: + fmt.Printf("Some event\n") + } + } + + sdl.Delay(16) + } + + return 0 +} + +func main() { + os.Exit(run()) +} diff --git a/examples/gfx/gfx.c b/examples/gfx/gfx.c new file mode 100644 index 0000000..8a5d55a --- /dev/null +++ b/examples/gfx/gfx.c @@ -0,0 +1,34 @@ +#include +#include +#include + +#define WIDTH (800) +#define HEIGHT (600) + +int main() +{ + SDL_Window *window; + SDL_Renderer *renderer; + Sint16 vx[] = { 100, 300, 200 }; + Sint16 vy[] = { 100, 100, 300 }; + + window = SDL_CreateWindow("SDL2 GFX", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL); + if (!window) { + fprintf(stderr, "error: %s\n", SDL_GetError()); + return -1; + } + + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + if (!renderer) { + fprintf(stderr, "error: %s\n", SDL_GetError()); + return -1; + } + + filledPolygonColor(renderer, vx, vy, 3, 0xFFFF0000); + + SDL_RenderPresent(renderer); + SDL_Delay(3000); + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); +} diff --git a/examples/gfx/gfx.go b/examples/gfx/gfx.go new file mode 100644 index 0000000..e0c32a7 --- /dev/null +++ b/examples/gfx/gfx.go @@ -0,0 +1,58 @@ +package main + +import ( + "fmt" + "os" + + "github.com/veandco/go-sdl2/gfx" + "github.com/veandco/go-sdl2/sdl" +) + +var winTitle string = "SDL2 GFX" +var winWidth, winHeight int32 = 800, 600 + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var vx, vy = make([]int16, 3), make([]int16, 3) + var err error + + if err = sdl.Init(sdl.INIT_EVERYTHING); err != nil { + fmt.Fprintf(os.Stderr, "Failed to initialize SDL: %s\n", err) + return 1 + } + defer sdl.Quit() + + if window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, winWidth, winHeight, sdl.WINDOW_SHOWN); err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 2 + } + defer window.Destroy() + + if renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED); err != nil { + fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err) + return 3 // don't use os.Exit(3); otherwise, previous deferred calls will never run + } + renderer.Clear() + defer renderer.Destroy() + + vx[0] = int16(winWidth / 3) + vy[0] = int16(winHeight / 3) + vx[1] = int16(winWidth * 2 / 3) + vy[1] = int16(winHeight / 3) + vx[2] = int16(winWidth / 2) + vy[2] = int16(winHeight * 2 / 3) + gfx.FilledPolygonColor(renderer, vx, vy, sdl.Color{0, 0, 255, 255}) + + gfx.CharacterColor(renderer, winWidth-16, 16, 'X', sdl.Color{255, 0, 0, 255}) + gfx.StringColor(renderer, 16, 16, "GFX Demo", sdl.Color{0, 255, 0, 255}) + + renderer.Present() + sdl.Delay(3000) + + return 0 +} + +func main() { + os.Exit(run()) +} diff --git a/examples/messagebox/messagebox.go b/examples/messagebox/messagebox.go new file mode 100644 index 0000000..d1011ff --- /dev/null +++ b/examples/messagebox/messagebox.go @@ -0,0 +1,48 @@ +package main + +import ( + "fmt" + + "github.com/veandco/go-sdl2/sdl" +) + +func main() { + buttons := []sdl.MessageBoxButtonData{ + {0, 0, "no"}, + {sdl.MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "yes"}, + {sdl.MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "cancel"}, + } + + colorScheme := sdl.MessageBoxColorScheme{ + Colors: [5]sdl.MessageBoxColor{ + sdl.MessageBoxColor{255, 0, 0}, + sdl.MessageBoxColor{0, 255, 0}, + sdl.MessageBoxColor{255, 255, 0}, + sdl.MessageBoxColor{0, 0, 255}, + sdl.MessageBoxColor{255, 0, 255}, + }, + } + + messageboxdata := sdl.MessageBoxData{ + sdl.MESSAGEBOX_INFORMATION, + nil, + "example message box", + "select a button", + int32(len(buttons)), + buttons, + &colorScheme, + } + + var buttonid int32 + var err error + if buttonid, err = sdl.ShowMessageBox(&messageboxdata); err != nil { + fmt.Println("error displaying message box") + return + } + + if buttonid == -1 { + fmt.Println("no selection") + } else { + fmt.Println("selection was", buttons[buttonid].Text) + } +} diff --git a/examples/opengl/opengl.go b/examples/opengl/opengl.go new file mode 100644 index 0000000..c63a0d7 --- /dev/null +++ b/examples/opengl/opengl.go @@ -0,0 +1,73 @@ +// author: HardWareGuy + +package main + +import ( + "fmt" + "github.com/go-gl/gl/v2.1/gl" + "github.com/veandco/go-sdl2/sdl" +) + +func main() { + var winTitle string = "Go-SDL2 + Go-GL" + var winWidth, winHeight int32 = 800, 600 + var window *sdl.Window + var context sdl.GLContext + var event sdl.Event + var running bool + var err error + + if err = sdl.Init(sdl.INIT_EVERYTHING); err != nil { + panic(err) + } + defer sdl.Quit() + + window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_OPENGL) + if err != nil { + panic(err) + } + defer window.Destroy() + context, err = sdl.GLCreateContext(window) + if err != nil { + panic(err) + } + defer sdl.GLDeleteContext(context) + + if err = gl.Init(); err != nil { + panic(err) + } + + gl.Enable(gl.DEPTH_TEST) + gl.ClearColor(0.2, 0.2, 0.3, 1.0) + gl.ClearDepth(1) + gl.DepthFunc(gl.LEQUAL) + gl.Viewport(0, 0, int32(winWidth), int32(winHeight)) + + running = true + for running { + for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() { + switch t := event.(type) { + case *sdl.QuitEvent: + running = false + case *sdl.MouseMotionEvent: + fmt.Printf("[%d ms] MouseMotion\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", t.Timestamp, t.Which, t.X, t.Y, t.XRel, t.YRel) + } + } + drawgl() + sdl.GLSwapWindow(window) + } +} + +func drawgl() { + gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) + + gl.Begin(gl.TRIANGLES) + gl.Color3f(1.0, 0.0, 0.0) + gl.Vertex2f(0.5, 0.0) + gl.Color3f(0.0, 1.0, 0.0) + gl.Vertex2f(-0.5, -0.5) + gl.Color3f(0.0, 0.0, 1.0) + gl.Vertex2f(-0.5, 0.5) + gl.End() +} diff --git a/examples/opengl3/opengl3.go b/examples/opengl3/opengl3.go new file mode 100644 index 0000000..af8a545 --- /dev/null +++ b/examples/opengl3/opengl3.go @@ -0,0 +1,277 @@ +package main + +import ( + "fmt" + gl "github.com/chsc/gogl/gl33" + "github.com/veandco/go-sdl2/sdl" + "math" + "runtime" + "time" +) + +func createprogram() gl.Uint { + // VERTEX SHADER + vs := gl.CreateShader(gl.VERTEX_SHADER) + vs_source := gl.GLString(vertexShaderSource) + gl.ShaderSource(vs, 1, &vs_source, nil) + gl.CompileShader(vs) + var vs_status gl.Int + gl.GetShaderiv(vs, gl.COMPILE_STATUS, &vs_status) + fmt.Printf("Compiled Vertex Shader: %v\n", vs_status) + + // FRAGMENT SHADER + fs := gl.CreateShader(gl.FRAGMENT_SHADER) + fs_source := gl.GLString(fragmentShaderSource) + gl.ShaderSource(fs, 1, &fs_source, nil) + gl.CompileShader(fs) + var fstatus gl.Int + gl.GetShaderiv(fs, gl.COMPILE_STATUS, &fstatus) + fmt.Printf("Compiled Fragment Shader: %v\n", fstatus) + + // CREATE PROGRAM + program := gl.CreateProgram() + gl.AttachShader(program, vs) + gl.AttachShader(program, fs) + fragoutstring := gl.GLString("outColor") + defer gl.GLStringFree(fragoutstring) + gl.BindFragDataLocation(program, gl.Uint(0), fragoutstring) + + gl.LinkProgram(program) + var linkstatus gl.Int + gl.GetProgramiv(program, gl.LINK_STATUS, &linkstatus) + fmt.Printf("Program Link: %v\n", linkstatus) + + return program +} + +var uniRoll float32 = 0.0 +var uniYaw float32 = 1.0 +var uniPitch float32 = 0.0 +var uniscale float32 = 0.3 +var yrot float32 = 20.0 +var zrot float32 = 0.0 +var xrot float32 = 0.0 +var UniScale gl.Int + +func main() { + var window *sdl.Window + var context sdl.GLContext + var event sdl.Event + var running bool + var err error + runtime.LockOSThread() + if err = sdl.Init(sdl.INIT_EVERYTHING); err != nil { + panic(err) + } + defer sdl.Quit() + window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, + sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_OPENGL) + if err != nil { + panic(err) + } + defer window.Destroy() + context, err = sdl.GLCreateContext(window) + if err != nil { + panic(err) + } + defer sdl.GLDeleteContext(context) + + gl.Init() + gl.Viewport(0, 0, gl.Sizei(winWidth), gl.Sizei(winHeight)) + // OPENGL FLAGS + gl.ClearColor(0.0, 0.1, 0.0, 1.0) + gl.Enable(gl.DEPTH_TEST) + gl.DepthFunc(gl.LESS) + gl.Enable(gl.BLEND) + gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) + + // VERTEX BUFFER + var vertexbuffer gl.Uint + gl.GenBuffers(1, &vertexbuffer) + gl.BindBuffer(gl.ARRAY_BUFFER, vertexbuffer) + gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(len(triangle_vertices)*4), gl.Pointer(&triangle_vertices[0]), gl.STATIC_DRAW) + + // COLOUR BUFFER + var colourbuffer gl.Uint + gl.GenBuffers(1, &colourbuffer) + gl.BindBuffer(gl.ARRAY_BUFFER, colourbuffer) + gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(len(triangle_colours)*4), gl.Pointer(&triangle_colours[0]), gl.STATIC_DRAW) + + // GUESS WHAT + program := createprogram() + + // VERTEX ARRAY + var VertexArrayID gl.Uint + gl.GenVertexArrays(1, &VertexArrayID) + gl.BindVertexArray(VertexArrayID) + gl.EnableVertexAttribArray(0) + gl.BindBuffer(gl.ARRAY_BUFFER, vertexbuffer) + gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, nil) + + // VERTEX ARRAY HOOK COLOURS + gl.EnableVertexAttribArray(1) + gl.BindBuffer(gl.ARRAY_BUFFER, colourbuffer) + gl.VertexAttribPointer(1, 3, gl.FLOAT, gl.FALSE, 0, nil) + + //UNIFORM HOOK + unistring := gl.GLString("scaleMove") + UniScale = gl.GetUniformLocation(program, unistring) + fmt.Printf("Uniform Link: %v\n", UniScale+1) + + gl.UseProgram(program) + + running = true + for running { + for event = sdl.PollEvent(); event != nil; event = + sdl.PollEvent() { + switch t := event.(type) { + case *sdl.QuitEvent: + running = false + case *sdl.MouseMotionEvent: + + xrot = float32(t.Y) / 2 + yrot = float32(t.X) / 2 + fmt.Printf("[%dms]MouseMotion\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", t.Timestamp, t.Which, t.X, t.Y, t.XRel, t.YRel) + } + } + drawgl() + sdl.GLSwapWindow(window) + } +} + +func drawgl() { + gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) + + uniYaw = yrot * (math.Pi / 180.0) + yrot = yrot - 1.0 + uniPitch = zrot * (math.Pi / 180.0) + zrot = zrot - 0.5 + uniRoll = xrot * (math.Pi / 180.0) + xrot = xrot - 0.2 + + gl.Uniform4f(UniScale, gl.Float(uniRoll), gl.Float(uniYaw), gl.Float(uniPitch), gl.Float(uniscale)) + gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) + gl.DrawArrays(gl.TRIANGLES, gl.Int(0), gl.Sizei(len(triangle_vertices)*4)) + + time.Sleep(50 * time.Millisecond) + +} + +const ( + winTitle = "OpenGL Shader" + winWidth = 640 + winHeight = 480 + vertexShaderSource = ` +#version 330 +layout (location = 0) in vec3 Position; +layout(location = 1) in vec3 vertexColor; +uniform vec4 scaleMove; +out vec3 fragmentColor; +void main() +{ +// YOU CAN OPTIMISE OUT cos(scaleMove.x) AND sin(scaleMove.y) AND UNIFORM THE VALUES IN + vec3 scale = Position.xyz * scaleMove.w; +// rotate on z pole + vec3 rotatez = vec3((scale.x * cos(scaleMove.x) - scale.y * sin(scaleMove.x)), (scale.x * sin(scaleMove.x) + scale.y * cos(scaleMove.x)), scale.z); +// rotate on y pole + vec3 rotatey = vec3((rotatez.x * cos(scaleMove.y) - rotatez.z * sin(scaleMove.y)), rotatez.y, (rotatez.x * sin(scaleMove.y) + rotatez.z * cos(scaleMove.y))); +// rotate on x pole + vec3 rotatex = vec3(rotatey.x, (rotatey.y * cos(scaleMove.z) - rotatey.z * sin(scaleMove.z)), (rotatey.y * sin(scaleMove.z) + rotatey.z * cos(scaleMove.z))); +// move +vec3 move = vec3(rotatex.xy, rotatex.z - 0.2); +// terrible perspective transform +vec3 persp = vec3( move.x / ( (move.z + 2) / 3 ) , + move.y / ( (move.z + 2) / 3 ) , + move.z); + + gl_Position = vec4(persp, 1.0); + fragmentColor = vertexColor; +} +` + fragmentShaderSource = ` +#version 330 +out vec4 outColor; +in vec3 fragmentColor; +void main() +{ + outColor = vec4(fragmentColor, 1.0); +} +` +) + +var triangle_vertices = []gl.Float{ + -1.0, -1.0, -1.0, + -1.0, -1.0, 1.0, + -1.0, 1.0, 1.0, + 1.0, 1.0, -1.0, + -1.0, -1.0, -1.0, + -1.0, 1.0, -1.0, + 1.0, -1.0, 1.0, + -1.0, -1.0, -1.0, + 1.0, -1.0, -1.0, + 1.0, 1.0, -1.0, + 1.0, -1.0, -1.0, + -1.0, -1.0, -1.0, + -1.0, -1.0, -1.0, + -1.0, 1.0, 1.0, + -1.0, 1.0, -1.0, + 1.0, -1.0, 1.0, + -1.0, -1.0, 1.0, + -1.0, -1.0, -1.0, + -1.0, 1.0, 1.0, + -1.0, -1.0, 1.0, + 1.0, -1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, -1.0, -1.0, + 1.0, 1.0, -1.0, + 1.0, -1.0, -1.0, + 1.0, 1.0, 1.0, + 1.0, -1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, -1.0, + -1.0, 1.0, -1.0, + 1.0, 1.0, 1.0, + -1.0, 1.0, -1.0, + -1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + -1.0, 1.0, 1.0, + 1.0, -1.0, 1.0} + +var triangle_colours = []gl.Float{ + 0.583, 0.771, 0.014, + 0.609, 0.115, 0.436, + 0.327, 0.483, 0.844, + 0.822, 0.569, 0.201, + 0.435, 0.602, 0.223, + 0.310, 0.747, 0.185, + 0.597, 0.770, 0.761, + 0.559, 0.436, 0.730, + 0.359, 0.583, 0.152, + 0.483, 0.596, 0.789, + 0.559, 0.861, 0.639, + 0.195, 0.548, 0.859, + 0.014, 0.184, 0.576, + 0.771, 0.328, 0.970, + 0.406, 0.615, 0.116, + 0.676, 0.977, 0.133, + 0.971, 0.572, 0.833, + 0.140, 0.616, 0.489, + 0.997, 0.513, 0.064, + 0.945, 0.719, 0.592, + 0.543, 0.021, 0.978, + 0.279, 0.317, 0.505, + 0.167, 0.620, 0.077, + 0.347, 0.857, 0.137, + 0.055, 0.953, 0.042, + 0.714, 0.505, 0.345, + 0.783, 0.290, 0.734, + 0.722, 0.645, 0.174, + 0.302, 0.455, 0.848, + 0.225, 0.587, 0.040, + 0.517, 0.713, 0.338, + 0.053, 0.959, 0.120, + 0.393, 0.621, 0.362, + 0.673, 0.211, 0.457, + 0.820, 0.883, 0.371, + 0.982, 0.099, 0.879} diff --git a/examples/render/render.go b/examples/render/render.go new file mode 100644 index 0000000..d457ddc --- /dev/null +++ b/examples/render/render.go @@ -0,0 +1,73 @@ +// author: Jacky Boen + +package main + +import ( + "fmt" + "github.com/veandco/go-sdl2/sdl" + "os" +) + +var winTitle string = "Go-SDL2 Render" +var winWidth, winHeight int32 = 800, 600 + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var points []sdl.Point + var rect sdl.Rect + var rects []sdl.Rect + + window, err := sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_SHOWN) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer window.Destroy() + + renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err) + return 2 + } + defer renderer.Destroy() + + renderer.Clear() + + renderer.SetDrawColor(255, 255, 255, 255) + renderer.DrawPoint(150, 300) + + renderer.SetDrawColor(0, 0, 255, 255) + renderer.DrawLine(0, 0, 200, 200) + + points = []sdl.Point{{0, 0}, {100, 300}, {100, 300}, {200, 0}} + renderer.SetDrawColor(255, 255, 0, 255) + renderer.DrawLines(points) + + rect = sdl.Rect{300, 0, 200, 200} + renderer.SetDrawColor(255, 0, 0, 255) + renderer.DrawRect(&rect) + + rects = []sdl.Rect{{400, 400, 100, 100}, {550, 350, 200, 200}} + renderer.SetDrawColor(0, 255, 255, 255) + renderer.DrawRects(rects) + + rect = sdl.Rect{250, 250, 200, 200} + renderer.SetDrawColor(0, 255, 0, 255) + renderer.FillRect(&rect) + + rects = []sdl.Rect{{500, 300, 100, 100}, {200, 300, 200, 200}} + renderer.SetDrawColor(255, 0, 255, 255) + renderer.FillRects(rects) + + renderer.Present() + + sdl.Delay(2000) + + return 0 +} + +func main() { + os.Exit(run()) +} diff --git a/examples/render_goroutines/render_goroutines.go b/examples/render_goroutines/render_goroutines.go new file mode 100644 index 0000000..2583b43 --- /dev/null +++ b/examples/render_goroutines/render_goroutines.go @@ -0,0 +1,122 @@ +package main + +import ( + "fmt" + "math/rand" + "os" + "sync" + + "github.com/veandco/go-sdl2/sdl" +) + +const ( + WindowTitle = "Go-SDL2 Render" + WindowWidth = 800 + WindowHeight = 600 + FrameRate = 60 + + RectWidth = 20 + RectHeight = 20 + NumRects = WindowHeight / RectHeight +) + +var rects [NumRects]sdl.Rect +var runningMutex sync.Mutex + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var err error + + sdl.Do(func() { + window, err = sdl.CreateWindow(WindowTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, WindowWidth, WindowHeight, sdl.WINDOW_OPENGL) + }) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer func() { + sdl.Do(func() { + window.Destroy() + }) + }() + + sdl.Do(func() { + renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) + }) + if err != nil { + fmt.Fprint(os.Stderr, "Failed to create renderer: %s\n", err) + return 2 + } + defer func() { + sdl.Do(func() { + renderer.Destroy() + }) + }() + + sdl.Do(func() { + renderer.Clear() + }) + + for i := range rects { + rects[i] = sdl.Rect{ + X: int32(rand.Int() % WindowWidth), + Y: int32(i * WindowHeight / len(rects)), + W: RectWidth, + H: RectHeight, + } + } + + running := true + for running { + sdl.Do(func() { + for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { + switch event.(type) { + case *sdl.QuitEvent: + runningMutex.Lock() + running = false + runningMutex.Unlock() + } + } + + renderer.Clear() + renderer.SetDrawColor(0, 0, 0, 0x20) + renderer.FillRect(&sdl.Rect{0, 0, WindowWidth, WindowHeight}) + }) + + // Do expensive stuff using goroutines + wg := sync.WaitGroup{} + for i := range rects { + wg.Add(1) + go func(i int) { + rects[i].X = (rects[i].X + 10) % WindowWidth + sdl.Do(func() { + renderer.SetDrawColor(0xff, 0xff, 0xff, 0xff) + renderer.DrawRect(&rects[i]) + }) + wg.Done() + }(i) + } + wg.Wait() + + sdl.Do(func() { + renderer.Present() + sdl.Delay(1000 / FrameRate) + }) + } + + return 0 +} + +func main() { + // os.Exit(..) must run AFTER sdl.Main(..) below; so keep track of exit + // status manually outside the closure passed into sdl.Main(..) below + var exitcode int + sdl.Main(func() { + exitcode = run() + }) + // os.Exit(..) must run here! If run in sdl.Main(..) above, it will cause + // premature quitting of sdl.Main(..) function; resource cleaning deferred + // calls/closing of channels may never run + os.Exit(exitcode) +} diff --git a/examples/render_queue/render_queue.go b/examples/render_queue/render_queue.go new file mode 100644 index 0000000..3890971 --- /dev/null +++ b/examples/render_queue/render_queue.go @@ -0,0 +1,156 @@ +package main + +import ( + "fmt" + "os" + + "github.com/veandco/go-sdl2/sdl" +) + +const ( + WindowTitle = "Go-SDL2 Render Queue" + WindowWidth = 800 + WindowHeight = 600 +) + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var points []sdl.Point + var rect sdl.Rect + var rects []sdl.Rect + var err error + + sdl.Do(func() { + window, err = sdl.CreateWindow(WindowTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, WindowWidth, WindowHeight, sdl.WINDOW_SHOWN) + }) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer func() { + sdl.Do(func() { + window.Destroy() + }) + }() + + sdl.Do(func() { + renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) + }) + if err != nil { + fmt.Fprint(os.Stderr, "Failed to create renderer: %s\n", err) + return 2 + } + + sdl.Do(func() { + renderer.Clear() + }) + defer func() { + sdl.Do(func() { + renderer.Destroy() + }) + }() + + go func() { + println("goroutine: A") + }() + + sdl.Do(func() { + renderer.SetDrawColor(255, 255, 255, 255) + renderer.DrawPoint(150, 300) + println("queue: A") + }) + + go func() { + println("goroutine: B") + }() + + sdl.Do(func() { + renderer.SetDrawColor(0, 0, 255, 255) + renderer.DrawLine(0, 0, 200, 200) + println("queue: B") + }) + + go func() { + println("goroutine: C") + }() + + sdl.Do(func() { + points = []sdl.Point{{0, 0}, {100, 300}, {100, 300}, {200, 0}} + renderer.SetDrawColor(255, 255, 0, 255) + renderer.DrawLines(points) + println("queue: C") + }) + + go func() { + println("goroutine: D") + }() + + sdl.Do(func() { + rect = sdl.Rect{300, 0, 200, 200} + renderer.SetDrawColor(255, 0, 0, 255) + renderer.DrawRect(&rect) + println("queue: D") + }) + + go func() { + println("goroutine: E") + }() + + sdl.Do(func() { + rects = []sdl.Rect{{400, 400, 100, 100}, {550, 350, 200, 200}} + renderer.SetDrawColor(0, 255, 255, 255) + renderer.DrawRects(rects) + println("queue: E") + }) + + go func() { + println("goroutine: F") + }() + + sdl.Do(func() { + rect = sdl.Rect{250, 250, 200, 200} + renderer.SetDrawColor(0, 255, 0, 255) + renderer.FillRect(&rect) + println("queue: F") + }) + + go func() { + println("goroutine: G") + }() + + sdl.Do(func() { + rects = []sdl.Rect{{500, 300, 100, 100}, {200, 300, 200, 200}} + renderer.SetDrawColor(255, 0, 255, 255) + renderer.FillRects(rects) + println("queue: G") + }) + + go func() { + println("goroutine: H") + }() + + sdl.Do(func() { + renderer.Present() + println("queue: H") + }) + + sdl.Do(func() { + sdl.Delay(2000) + }) + + return 0 +} + +func main() { + // os.Exit(..) must run AFTER sdl.Main(..) below; so keep track of exit + // status manually outside the closure passed into sdl.Main(..) below + var exitcode int + sdl.Main(func() { + exitcode = run() + }) + // os.Exit(..) must run here! If run in sdl.Main(..) above, it will cause + // premature quitting of sdl.Main(..) function; resource cleaning deferred + // calls/closing of channels may never run + os.Exit(exitcode) +} diff --git a/examples/syswminfo/syswminfo.go b/examples/syswminfo/syswminfo.go new file mode 100644 index 0000000..06d4576 --- /dev/null +++ b/examples/syswminfo/syswminfo.go @@ -0,0 +1,49 @@ +// author: Jacky Boen + +package main + +import ( + "fmt" + "github.com/veandco/go-sdl2/sdl" + "os" +) + +func main() { + var window *sdl.Window + var info *sdl.SysWMInfo + var subsystem string + var err error + + window, err = sdl.CreateWindow("", 0, 0, 0, 0, sdl.WINDOW_HIDDEN) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + os.Exit(1) + } + defer window.Destroy() + + info, err = window.GetWMInfo() + if err == nil { + switch info.Subsystem { + case sdl.SYSWM_UNKNOWN: + subsystem = "An unknown system!" + case sdl.SYSWM_WINDOWS: + subsystem = "Microsoft Windows(TM)" + case sdl.SYSWM_X11: + subsystem = "X Window System" + case sdl.SYSWM_DIRECTFB: + subsystem = "DirectFB" + case sdl.SYSWM_COCOA: + subsystem = "Apple OS X" + case sdl.SYSWM_UIKIT: + subsystem = "UIKit" + } + + fmt.Printf("This program is running SDL version %d.%d.%d on %s\n", + info.Version.Major, + info.Version.Minor, + info.Version.Patch, + subsystem) + } else { + fmt.Fprintf(os.Stderr, "Couldn't get window information: %s\n", err) + } +} diff --git a/examples/text/text.go b/examples/text/text.go new file mode 100644 index 0000000..aa57a7d --- /dev/null +++ b/examples/text/text.go @@ -0,0 +1,65 @@ +package main + +import ( + "fmt" + "os" + + "github.com/veandco/go-sdl2/sdl" + "github.com/veandco/go-sdl2/ttf" +) + +var winTitle string = "Text" +var winWidth, winHeight int32 = 800, 600 + +func run() int { + var window *sdl.Window + var font *ttf.Font + var surface *sdl.Surface + var solid *sdl.Surface + var err error + + sdl.Init(sdl.INIT_VIDEO) + + if err := ttf.Init(); err != nil { + fmt.Fprintf(os.Stderr, "Failed to initialize TTF: %s\n", err) + return 1 + } + + if window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, winWidth, winHeight, sdl.WINDOW_SHOWN); err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 2 + } + defer window.Destroy() + + if font, err = ttf.OpenFont("../../assets/test.ttf", 32); err != nil { + fmt.Fprintf(os.Stderr, "Failed to open font: %s\n", err) + return 4 + } + defer font.Close() + + if solid, err = font.RenderUTF8Solid("Hello, World!", sdl.Color{255, 0, 0, 255}); err != nil { + fmt.Fprintf(os.Stderr, "Failed to render text: %s\n", err) + return 5 + } + defer solid.Free() + + if surface, err = window.GetSurface(); err != nil { + fmt.Fprintf(os.Stderr, "Failed to get window surface: %s\n", err) + return 6 + } + + if err = solid.Blit(nil, surface, nil); err != nil { + fmt.Fprintf(os.Stderr, "Failed to put text on window surface: %s\n", err) + return 7 + } + + // Show the pixels for a while + window.UpdateSurface() + sdl.Delay(3000) + + return 0 +} + +func main() { + os.Exit(run()) +} diff --git a/examples/texture/texture.go b/examples/texture/texture.go new file mode 100644 index 0000000..738e0c8 --- /dev/null +++ b/examples/texture/texture.go @@ -0,0 +1,66 @@ +// author: Jacky Boen + +package main + +import ( + "fmt" + "github.com/veandco/go-sdl2/sdl" + "os" +) + +var winTitle string = "Go-SDL2 Texture" +var winWidth, winHeight int32 = 800, 600 +var imageName string = "../../assets/test.bmp" + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var image *sdl.Surface + var texture *sdl.Texture + var src, dst sdl.Rect + var err error + + window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_SHOWN) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer window.Destroy() + + renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err) + return 2 + } + defer renderer.Destroy() + + image, err = sdl.LoadBMP(imageName) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to load BMP: %s\n", err) + return 3 + } + defer image.Free() + + texture, err = renderer.CreateTextureFromSurface(image) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create texture: %s\n", err) + return 4 + } + defer texture.Destroy() + + src = sdl.Rect{0, 0, 512, 512} + dst = sdl.Rect{100, 50, 512, 512} + + renderer.Clear() + renderer.Copy(texture, &src, &dst) + renderer.Present() + + sdl.Delay(2000) + + return 0 +} + +func main() { + os.Exit(run()) +} diff --git a/examples/texture_png/texture_png.c b/examples/texture_png/texture_png.c new file mode 100644 index 0000000..fe75fb8 --- /dev/null +++ b/examples/texture_png/texture_png.c @@ -0,0 +1,57 @@ +// Test program in C to see behavior of IMG_Load() + +#include +#include + +static const int WIN_WIDTH = 800; +static const int WIN_HEIGHT = 600; + +int main() +{ + SDL_Window *window = SDL_CreateWindow( + "Go-SDL2 Texture - C version", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + WIN_WIDTH, WIN_HEIGHT, + SDL_WINDOW_SHOWN); + if (!window) { + fprintf(stderr, "Failed to create window: %s\n", SDL_GetError()); + return 1; + } + + SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + if (!renderer) { + fprintf(stderr, "Failed to create renderer: %s\n", SDL_GetError()); + return 2; + } + + SDL_Surface *image = IMG_Load("../../assets/test.png"); + if (!image) { + fprintf(stderr, "Failed to load PNG: %s\n", SDL_GetError()); + return 3; + } + + SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, image); + if (!texture) { + fprintf(stderr, "Failed to cerate texture: %s\n", SDL_GetError()); + return 4; + } + + SDL_Rect src = {0, 0, 512, 512}; + SDL_Rect dst = {100, 50, 512, 512}; + SDL_Rect bound = {0, 0, WIN_WIDTH, WIN_HEIGHT}; + + SDL_RenderClear(renderer); + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + SDL_RenderFillRect(renderer, &bound); + SDL_RenderCopy(renderer, texture, &src, &dst); + SDL_RenderPresent(renderer); + + SDL_Delay(2000); + + SDL_DestroyTexture(texture); + SDL_FreeSurface(image); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + + return 0; +} diff --git a/examples/texture_png/texture_png.go b/examples/texture_png/texture_png.go new file mode 100644 index 0000000..1a000d2 --- /dev/null +++ b/examples/texture_png/texture_png.go @@ -0,0 +1,68 @@ +// author: Jacky Boen + +package main + +import ( + "fmt" + "github.com/veandco/go-sdl2/img" + "github.com/veandco/go-sdl2/sdl" + "os" +) + +var winTitle string = "Go-SDL2 Texture" +var winWidth, winHeight int32 = 800, 600 +var imageName string = "../../assets/test.png" + +func run() int { + var window *sdl.Window + var renderer *sdl.Renderer + var texture *sdl.Texture + var src, dst sdl.Rect + var err error + + window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, + winWidth, winHeight, sdl.WINDOW_SHOWN) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err) + return 1 + } + defer window.Destroy() + + renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err) + return 2 + } + defer renderer.Destroy() + + image, err := img.Load(imageName) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to load PNG: %s\n", err) + return 3 + } + defer image.Free() + + texture, err = renderer.CreateTextureFromSurface(image) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create texture: %s\n", err) + return 4 + } + defer texture.Destroy() + + src = sdl.Rect{0, 0, 512, 512} + dst = sdl.Rect{100, 50, 512, 512} + + renderer.Clear() + renderer.SetDrawColor(255, 0, 0, 255) + renderer.FillRect(&sdl.Rect{0, 0, int32(winWidth), int32(winHeight)}) + renderer.Copy(texture, &src, &dst) + renderer.Present() + + sdl.Delay(2000) + + return 0 +} + +func main() { + os.Exit(run()) +}