mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 02:42:02 +01:00
Implement ui.cocoa
This commit is contained in:
parent
54893c3031
commit
983aeec03b
@ -8,8 +8,8 @@ import (
|
|||||||
"github.com/hajimehoshi/go.ebiten/example/game/rects"
|
"github.com/hajimehoshi/go.ebiten/example/game/rects"
|
||||||
"github.com/hajimehoshi/go.ebiten/example/game/rotating"
|
"github.com/hajimehoshi/go.ebiten/example/game/rotating"
|
||||||
"github.com/hajimehoshi/go.ebiten/example/game/sprites"
|
"github.com/hajimehoshi/go.ebiten/example/game/sprites"
|
||||||
_ "github.com/hajimehoshi/go.ebiten/ui/cocoa"
|
"github.com/hajimehoshi/go.ebiten/ui/cocoa"
|
||||||
"github.com/hajimehoshi/go.ebiten/ui/glut"
|
_ "github.com/hajimehoshi/go.ebiten/ui/glut"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
@ -41,5 +41,5 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const screenScale = 2
|
const screenScale = 2
|
||||||
glut.Run(game, 256, 240, screenScale, "Ebiten Demo")
|
cocoa.Run(game, 256, 240, screenScale, "Ebiten Demo")
|
||||||
}
|
}
|
||||||
|
@ -10,15 +10,112 @@ package cocoa
|
|||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/go.ebiten"
|
"github.com/hajimehoshi/go.ebiten"
|
||||||
_ "github.com/hajimehoshi/go.ebiten/graphics"
|
// "github.com/hajimehoshi/go.ebiten/graphics"
|
||||||
_ "github.com/hajimehoshi/go.ebiten/graphics/opengl"
|
"github.com/hajimehoshi/go.ebiten/graphics/opengl"
|
||||||
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type UI struct {
|
||||||
|
game ebiten.Game
|
||||||
|
screenWidth int
|
||||||
|
screenHeight int
|
||||||
|
screenScale int
|
||||||
|
graphicsDevice *opengl.Device
|
||||||
|
inited chan bool
|
||||||
|
updating chan bool
|
||||||
|
updated chan bool
|
||||||
|
input chan ebiten.InputState
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentUI *UI
|
||||||
|
|
||||||
|
//export ebiten_EbitenOpenGLView_Initialized
|
||||||
|
func ebiten_EbitenOpenGLView_Initialized() {
|
||||||
|
if currentUI.graphicsDevice != nil {
|
||||||
|
panic("The graphics device is already initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
currentUI.graphicsDevice = opengl.NewDevice(
|
||||||
|
currentUI.screenWidth,
|
||||||
|
currentUI.screenHeight,
|
||||||
|
currentUI.screenScale)
|
||||||
|
currentUI.graphicsDevice.Init()
|
||||||
|
|
||||||
|
currentUI.game.Init(currentUI.graphicsDevice.TextureFactory())
|
||||||
|
|
||||||
|
currentUI.inited <- true
|
||||||
|
}
|
||||||
|
|
||||||
|
//export ebiten_EbitenOpenGLView_Updating
|
||||||
|
func ebiten_EbitenOpenGLView_Updating() {
|
||||||
|
<-currentUI.updating
|
||||||
|
currentUI.graphicsDevice.Update(currentUI.game.Draw)
|
||||||
|
currentUI.updated <- true
|
||||||
|
}
|
||||||
|
|
||||||
|
//export ebiten_EbitenOpenGLView_InputUpdated
|
||||||
|
func ebiten_EbitenOpenGLView_InputUpdated(x, y C.int) {
|
||||||
|
currentUI.input <- ebiten.InputState{int(x), int(y)}
|
||||||
|
}
|
||||||
|
|
||||||
func Run(game ebiten.Game, screenWidth, screenHeight, screenScale int,
|
func Run(game ebiten.Game, screenWidth, screenHeight, screenScale int,
|
||||||
title string) {
|
title string) {
|
||||||
cTitle := C.CString(title)
|
cTitle := C.CString(title)
|
||||||
defer C.free(unsafe.Pointer(cTitle))
|
defer C.free(unsafe.Pointer(cTitle))
|
||||||
|
|
||||||
C.Run(C.size_t(screenWidth), C.size_t(screenHeight), C.size_t(screenScale), cTitle)
|
currentUI = &UI{
|
||||||
|
game: game,
|
||||||
|
screenWidth: screenWidth,
|
||||||
|
screenHeight: screenHeight,
|
||||||
|
screenScale: screenScale,
|
||||||
|
inited: make(chan bool),
|
||||||
|
updating: make(chan bool),
|
||||||
|
updated: make(chan bool),
|
||||||
|
input: make(chan ebiten.InputState),
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
frameTime := time.Duration(
|
||||||
|
int64(time.Second) / int64(ebiten.FPS))
|
||||||
|
tick := time.Tick(frameTime)
|
||||||
|
gameContext := &GameContext{
|
||||||
|
screenWidth: screenWidth,
|
||||||
|
screenHeight: screenHeight,
|
||||||
|
inputState: ebiten.InputState{-1, -1},
|
||||||
|
}
|
||||||
|
<-currentUI.inited
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case gameContext.inputState = <-currentUI.input:
|
||||||
|
case <-tick:
|
||||||
|
game.Update(gameContext)
|
||||||
|
case currentUI.updating <- true:
|
||||||
|
<-currentUI.updated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
C.Run(C.size_t(screenWidth),
|
||||||
|
C.size_t(screenHeight),
|
||||||
|
C.size_t(screenScale),
|
||||||
|
cTitle)
|
||||||
|
}
|
||||||
|
|
||||||
|
type GameContext struct {
|
||||||
|
screenWidth int
|
||||||
|
screenHeight int
|
||||||
|
inputState ebiten.InputState
|
||||||
|
}
|
||||||
|
|
||||||
|
func (context *GameContext) ScreenWidth() int {
|
||||||
|
return context.screenWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
func (context *GameContext) ScreenHeight() int {
|
||||||
|
return context.screenHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
func (context *GameContext) InputState() ebiten.InputState {
|
||||||
|
return context.inputState
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
#include "ebiten_opengl_view.h"
|
#include "ebiten_opengl_view.h"
|
||||||
|
|
||||||
|
void ebiten_EbitenOpenGLView_Initialized(void);
|
||||||
|
void ebiten_EbitenOpenGLView_Updating(void);
|
||||||
|
void ebiten_EbitenOpenGLView_InputUpdated(int x, int y);
|
||||||
|
|
||||||
// Reference:
|
// Reference:
|
||||||
// http://developer.apple.com/library/mac/#qa/qa1385/_index.html
|
// http://developer.apple.com/library/mac/#qa/qa1385/_index.html
|
||||||
// http://www.alecjacobson.com/weblog/?p=2185
|
// http://www.alecjacobson.com/weblog/?p=2185
|
||||||
@ -28,15 +32,9 @@ EbitenDisplayLinkCallback(CVDisplayLinkRef displayLink,
|
|||||||
@implementation EbitenOpenGLView {
|
@implementation EbitenOpenGLView {
|
||||||
@private
|
@private
|
||||||
CVDisplayLinkRef displayLink_;
|
CVDisplayLinkRef displayLink_;
|
||||||
updating* updating_;
|
size_t screenWidth_;
|
||||||
//ebiten::input* input_;
|
size_t screenHeight_;
|
||||||
}
|
size_t screenScale_;
|
||||||
|
|
||||||
- (id)init {
|
|
||||||
if (self = [super init]) {
|
|
||||||
self->updating_ = NULL;
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
@ -48,7 +46,7 @@ EbitenDisplayLinkCallback(CVDisplayLinkRef displayLink,
|
|||||||
[super prepareOpenGL];
|
[super prepareOpenGL];
|
||||||
NSOpenGLContext* openGLContext = [self openGLContext];
|
NSOpenGLContext* openGLContext = [self openGLContext];
|
||||||
assert(openGLContext != nil);
|
assert(openGLContext != nil);
|
||||||
GLint const swapInterval = 1;
|
GLint swapInterval = 1;
|
||||||
[openGLContext setValues:&swapInterval
|
[openGLContext setValues:&swapInterval
|
||||||
forParameter:NSOpenGLCPSwapInterval];
|
forParameter:NSOpenGLCPSwapInterval];
|
||||||
CVDisplayLinkCreateWithActiveCGDisplays(&self->displayLink_);
|
CVDisplayLinkCreateWithActiveCGDisplays(&self->displayLink_);
|
||||||
@ -62,40 +60,24 @@ EbitenDisplayLinkCallback(CVDisplayLinkRef displayLink,
|
|||||||
cglContext,
|
cglContext,
|
||||||
cglPixelFormat);
|
cglPixelFormat);
|
||||||
CVDisplayLinkStart(self->displayLink_);
|
CVDisplayLinkStart(self->displayLink_);
|
||||||
|
|
||||||
|
ebiten_EbitenOpenGLView_Initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime {
|
- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime {
|
||||||
(void)outputTime;
|
(void)outputTime;
|
||||||
if (!self->updating_) {
|
|
||||||
return kCVReturnSuccess;
|
|
||||||
}
|
|
||||||
NSOpenGLContext* context = [self openGLContext];
|
NSOpenGLContext* context = [self openGLContext];
|
||||||
assert(context != nil);
|
assert(context != nil);
|
||||||
[context makeCurrentContext];
|
[context makeCurrentContext];
|
||||||
bool terminated = false;
|
|
||||||
{
|
{
|
||||||
CGLLockContext((CGLContextObj)[context CGLContextObj]);
|
CGLLockContext((CGLContextObj)[context CGLContextObj]);
|
||||||
terminated = self->updating_();
|
ebiten_EbitenOpenGLView_Updating();
|
||||||
[context flushBuffer];
|
[context flushBuffer];
|
||||||
CGLUnlockContext((CGLContextObj)[context CGLContextObj]);
|
CGLUnlockContext((CGLContextObj)[context CGLContextObj]);
|
||||||
}
|
}
|
||||||
if (terminated) {
|
|
||||||
//CVDisplayLinkStop(self->displayLink_);
|
|
||||||
[NSApp terminate:nil];
|
|
||||||
return kCVReturnSuccess;
|
|
||||||
}
|
|
||||||
return kCVReturnSuccess;
|
return kCVReturnSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setUpdatingFunc:(updating*)func {
|
|
||||||
self->updating_ = func;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
// - (void)setInput:(ebiten::input&)input {
|
|
||||||
// self->input_ = &input;
|
|
||||||
// }
|
|
||||||
|
|
||||||
- (BOOL)isFlipped {
|
- (BOOL)isFlipped {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
@ -103,40 +85,50 @@ EbitenDisplayLinkCallback(CVDisplayLinkRef displayLink,
|
|||||||
- (void)mouseDown:(NSEvent*)theEvent {
|
- (void)mouseDown:(NSEvent*)theEvent {
|
||||||
NSPoint location = [self convertPoint:[theEvent locationInWindow]
|
NSPoint location = [self convertPoint:[theEvent locationInWindow]
|
||||||
fromView:nil];
|
fromView:nil];
|
||||||
// TODO
|
int x = location.x / self->screenScale_;
|
||||||
/*
|
int y = location.y / self->screenScale_;
|
||||||
if (self->input_) {
|
if (x < 0) {
|
||||||
int x = location.x;
|
x = 0;
|
||||||
int y = location.y;
|
} else if (self->screenWidth_<= x) {
|
||||||
// TODO: Screen size
|
x = self->screenWidth_ - 1;
|
||||||
self->input_->set_touches_real_location(0,
|
}
|
||||||
static_cast<int>(x),
|
if (y < 0) {
|
||||||
static_cast<int>(y));
|
y = 0;
|
||||||
self->input_->set_touched(0, true);
|
} else if (self->screenHeight_<= y) {
|
||||||
}*/
|
y = self->screenHeight_ - 1;
|
||||||
|
}
|
||||||
|
ebiten_EbitenOpenGLView_InputUpdated(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseUp:(NSEvent*)theEvent {
|
- (void)mouseUp:(NSEvent*)theEvent {
|
||||||
(void)theEvent;
|
(void)theEvent;
|
||||||
// TODO
|
ebiten_EbitenOpenGLView_InputUpdated(-1, -1);
|
||||||
/*if (self->input_) {
|
|
||||||
self->input_->set_touches_real_location(0, -1, -1);
|
|
||||||
self->input_->set_touched(0, false);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseDragged:(NSEvent*)theEvent {
|
- (void)mouseDragged:(NSEvent*)theEvent {
|
||||||
NSPoint location = [self convertPoint:[theEvent locationInWindow]
|
NSPoint location = [self convertPoint:[theEvent locationInWindow]
|
||||||
fromView:nil];
|
fromView:nil];
|
||||||
// TODO
|
int x = location.x / self->screenScale_;
|
||||||
/*if (self->input_) {
|
int y = location.y / self->screenScale_;
|
||||||
int x = location.x;
|
if (x < 0) {
|
||||||
int y = location.y;
|
x = 0;
|
||||||
self->input_->set_touches_real_location(0,
|
} else if (self->screenWidth_<= x) {
|
||||||
static_cast<int>(x),
|
x = self->screenWidth_ - 1;
|
||||||
static_cast<int>(y));
|
}
|
||||||
self->input_->set_touched(0, true);
|
if (y < 0) {
|
||||||
}*/
|
y = 0;
|
||||||
|
} else if (self->screenHeight_<= y) {
|
||||||
|
y = self->screenHeight_ - 1;
|
||||||
|
}
|
||||||
|
ebiten_EbitenOpenGLView_InputUpdated(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setScreenWidth:(size_t)screenWidth
|
||||||
|
screenHeight:(size_t)screenHeight
|
||||||
|
screenScale:(size_t)screenScale {
|
||||||
|
self->screenWidth_ = screenWidth;
|
||||||
|
self->screenHeight_ = screenHeight;
|
||||||
|
self->screenScale_ = screenScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import <QuartzCore/QuartzCore.h>
|
#import <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
typedef bool updating(void);
|
|
||||||
|
|
||||||
@interface EbitenOpenGLView : NSOpenGLView
|
@interface EbitenOpenGLView : NSOpenGLView
|
||||||
|
|
||||||
- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime;
|
- (CVReturn)getFrameForTime:(CVTimeStamp const*)outputTime;
|
||||||
- (void)setUpdatingFunc:(updating*)updatingFunc;
|
- (void)setScreenWidth:(size_t)screenWidth
|
||||||
|
screenHeight:(size_t)screenHeight
|
||||||
|
screenScale:(size_t)screenScale;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
#import "ebiten_opengl_view.h"
|
#import "ebiten_opengl_view.h"
|
||||||
#import "ebiten_window.h"
|
#import "ebiten_window.h"
|
||||||
|
|
||||||
static NSWindow* generateWindow(size_t width, size_t height) {
|
static NSWindow* generateWindow(size_t width, size_t height, size_t scale, const char* title) {
|
||||||
EbitenWindow* window = [[EbitenWindow alloc]
|
EbitenWindow* window = [[EbitenWindow alloc]
|
||||||
initWithSize:NSMakeSize(width, height)];
|
initWithSize:NSMakeSize(width * scale, height * scale)];
|
||||||
assert(window != nil);
|
assert(window != nil);
|
||||||
|
|
||||||
NSRect const rect = NSMakeRect(0, 0, width, height);
|
NSRect const rect = NSMakeRect(0, 0, width * scale, height * scale);
|
||||||
NSOpenGLPixelFormatAttribute const attributes[] = {
|
NSOpenGLPixelFormatAttribute const attributes[] = {
|
||||||
NSOpenGLPFAWindow,
|
NSOpenGLPFAWindow,
|
||||||
NSOpenGLPFADoubleBuffer,
|
NSOpenGLPFADoubleBuffer,
|
||||||
@ -24,7 +24,11 @@ static NSWindow* generateWindow(size_t width, size_t height) {
|
|||||||
EbitenOpenGLView* glView =
|
EbitenOpenGLView* glView =
|
||||||
[[EbitenOpenGLView alloc] initWithFrame:rect
|
[[EbitenOpenGLView alloc] initWithFrame:rect
|
||||||
pixelFormat:format];
|
pixelFormat:format];
|
||||||
|
[glView setScreenWidth:width
|
||||||
|
screenHeight:height
|
||||||
|
screenScale:scale];
|
||||||
[window setContentView:glView];
|
[window setContentView:glView];
|
||||||
|
[window setTitle: [[NSString alloc] initWithUTF8String:title]];
|
||||||
//[window makeFirstResponder:glView];
|
//[window makeFirstResponder:glView];
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
@ -32,7 +36,7 @@ static NSWindow* generateWindow(size_t width, size_t height) {
|
|||||||
|
|
||||||
void Run(size_t width, size_t height, size_t scale, const char* title) {
|
void Run(size_t width, size_t height, size_t scale, const char* title) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
NSWindow* window = generateWindow(width * scale, height * scale);
|
NSWindow* window = generateWindow(width, height, scale, title);
|
||||||
EbitenController* controller = [[EbitenController alloc]
|
EbitenController* controller = [[EbitenController alloc]
|
||||||
initWithWindow:window];
|
initWithWindow:window];
|
||||||
NSApplication* app = [NSApplication sharedApplication];
|
NSApplication* app = [NSApplication sharedApplication];
|
||||||
|
@ -78,13 +78,10 @@ func idle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func new(screenWidth, screenHeight, screenScale int, title string) *GlutUI {
|
func new(screenWidth, screenHeight, screenScale int, title string) *GlutUI {
|
||||||
graphicsDevice := opengl.NewDevice(
|
|
||||||
screenWidth, screenHeight, screenScale)
|
|
||||||
ui := &GlutUI{
|
ui := &GlutUI{
|
||||||
glutInputting: make(chan glutInputEvent, 10),
|
glutInputting: make(chan glutInputEvent, 10),
|
||||||
graphicsDevice: graphicsDevice,
|
updating: make(chan func(graphics.Context)),
|
||||||
updating: make(chan func(graphics.Context)),
|
updated: make(chan bool),
|
||||||
updated: make(chan bool),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cargs := []*C.char{}
|
cargs := []*C.char{}
|
||||||
@ -109,11 +106,6 @@ func new(screenWidth, screenHeight, screenScale int, title string) *GlutUI {
|
|||||||
defer C.free(unsafe.Pointer(cTitle))
|
defer C.free(unsafe.Pointer(cTitle))
|
||||||
C.glutCreateWindow(cTitle)
|
C.glutCreateWindow(cTitle)
|
||||||
|
|
||||||
// Set the callbacks
|
|
||||||
C.setGlutFuncs()
|
|
||||||
|
|
||||||
graphicsDevice.Init()
|
|
||||||
|
|
||||||
return ui
|
return ui
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,6 +113,11 @@ func Run(game ebiten.Game, screenWidth, screenHeight, screenScale int, title str
|
|||||||
ui := new(screenWidth, screenHeight, screenScale, title)
|
ui := new(screenWidth, screenHeight, screenScale, title)
|
||||||
currentUI = ui
|
currentUI = ui
|
||||||
|
|
||||||
|
graphicsDevice := opengl.NewDevice(
|
||||||
|
screenWidth, screenHeight, screenScale)
|
||||||
|
ui.graphicsDevice = graphicsDevice
|
||||||
|
graphicsDevice.Init()
|
||||||
|
|
||||||
game.Init(ui.graphicsDevice.TextureFactory())
|
game.Init(ui.graphicsDevice.TextureFactory())
|
||||||
|
|
||||||
input := make(chan ebiten.InputState)
|
input := make(chan ebiten.InputState)
|
||||||
@ -170,6 +167,9 @@ func Run(game ebiten.Game, screenWidth, screenHeight, screenScale int, title str
|
|||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// Set the callbacks
|
||||||
|
C.setGlutFuncs()
|
||||||
|
|
||||||
C.glutMainLoop()
|
C.glutMainLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user