// Get the contents of the window's event queue and evacuate it. func (wi *windowInternal) pollEvents(block bool) ([]Event, []ThreadError) { // clear the events before and after wi.events = nil defer func() { wi.events = nil wi.eventErrors = nil }() // We process the window events only if we own it if wi.callback != nil { return nil, nil } // Wait for messages if we're blocking if block { if C.WaitMessage() == 0 { // TODO error check } } for message := (C.MSG{}); C.__PeekMessage(&message, wi.window.Handle, 0, 0, C.PM_REMOVE) == C.TRUE; { C.TranslateMessage(&message) C.DispatchMessage(&message) // if the last one is fatal, return if len(wi.eventErrors) != 0 && wi.eventErrors[len(wi.eventErrors)-1].Fatal() { break } } return wi.events, wi.eventErrors }
func (window *Win32Window) Peek() bool { var msg C.MSG res := C.PeekMessageA((*C.struct_tagMSG)(unsafe.Pointer(&msg)), nil, 0, 0, C.PM_REMOVE) if res == 1 { C.TranslateMessage(&msg) C.DispatchMessage(&msg) if msg.message == C.WM_QUIT { window.WndProc(window.hwnd, msg.message, 0, 0) } return true } return false }
func main() { // TODO enable VSync in D3D windowHandle, err := windows.OpenWindow(windowProc, windowW, windowH) check(err) window := C.HWND(windowHandle) C.SetWindowText( window, (*C.WCHAR)(syscall.StringToUTF16Ptr("Gophette's Adventure")), ) check(mixer.Init()) defer mixer.Close() C.ShowCursor(0) defer C.ShowCursor(1) check(d3d9.Init()) defer d3d9.Close() d3d, err := d3d9.Create(d3d9.SDK_VERSION) check(err) defer d3d.Release() var maxScreenW, maxScreenH uint for i := uint(0); i < d3d.GetAdapterCount(); i++ { mode, err := d3d.GetAdapterDisplayMode(i) if err == nil { if mode.Width > maxScreenW { maxScreenW = mode.Width } if mode.Height > maxScreenH { maxScreenH = mode.Height } } } if maxScreenW == 0 || maxScreenH == 0 { panic("no monitor detected") } device, _, err := d3d.CreateDevice( d3d9.ADAPTER_DEFAULT, d3d9.DEVTYPE_HAL, windowHandle, d3d9.CREATE_HARDWARE_VERTEXPROCESSING, d3d9.PRESENT_PARAMETERS{ BackBufferWidth: maxScreenW, BackBufferHeight: maxScreenH, BackBufferFormat: d3d9.FMT_A8R8G8B8, BackBufferCount: 1, Windowed: true, SwapEffect: d3d9.SWAPEFFECT_DISCARD, HDeviceWindow: windowHandle, }, ) check(err) defer device.Release() check(device.SetRenderState(d3d9.RS_CULLMODE, uint32(d3d9.CULL_CW))) check(device.SetRenderState(d3d9.RS_SRCBLEND, d3d9.BLEND_SRCALPHA)) check(device.SetRenderState(d3d9.RS_DESTBLEND, d3d9.BLEND_INVSRCALPHA)) check(device.SetRenderState(d3d9.RS_ALPHABLENDENABLE, 1)) camera = newWindowCamera(windowW, windowH) graphics := newWindowsGraphics(device, camera) defer graphics.close() assetLoader := newWindowsAssetLoader(device, graphics, camera) defer assetLoader.close() // charIndex selects which character is being controlled by the user, for // the final game this must be 0 but for creating the "AI" for Barney, set // this to 1 and delete the recorded inputs so they are not applied // additionally to the user controls const recordingAI = false // NOTE switch for development mode if !recordingAI { charIndex = 0 } else { charIndex = 1 recordedInputs = recordedInputs[:0] recordingInput = true } game = NewGame( assetLoader, graphics, camera, charIndex, ) music := assetLoader.LoadSound("music_wav") go func() { for { music.PlayOnce() time.Sleep(music.Length() + 5*time.Second) } }() toggleFullscreen(window) frameTime := time.Second / 65 lastUpdate := time.Now().Add(-frameTime) var msg C.MSG C.PeekMessage(&msg, nil, 0, 0, C.PM_NOREMOVE) for msg.message != C.WM_QUIT { if C.PeekMessage(&msg, nil, 0, 0, C.PM_REMOVE) != 0 { C.TranslateMessage(&msg) C.DispatchMessage(&msg) } else { now := time.Now() dt := now.Sub(lastUpdate) if dt > frameTime { game.Update() lastUpdate = now } check(device.SetViewport( d3d9.VIEWPORT{0, 0, uint32(windowW), uint32(windowH), 0, 1}, )) check(device.Clear( nil, d3d9.CLEAR_TARGET, d3d9.ColorRGB(0, 95, 83), 1, 0, )) game.Render() graphics.flush() check(device.Present( &d3d9.RECT{0, 0, int32(windowW), int32(windowH)}, nil, nil, nil, )) } } }