1 /** 2 * Copyright © Novelate 2020 3 * License: MIT (https://github.com/Novelate/NovelateEngine/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 * Website: https://novelate.com/ 6 * ------ 7 * Novelate is a free and open-source visual novel engine and framework written in the D programming language. 8 * It can be used freely for both personal and commercial projects. 9 * ------ 10 * Module Description: 11 * This module is used for external bindings to dsfml. Types and functions should only be exposed through internal types ex. RenderWindow is only referenced through ExternalWindow. 12 * This is the main module for external bindings and all possible bindings should reference this module in terms of implementation. 13 */ 14 module novelate.dsfmlbinding; 15 16 import novelate.buildstate; 17 18 static if (useSFML && !useDerelict) 19 { 20 import novelate.external.core; 21 22 private 23 { 24 import dsfml.graphics; 25 import dsfml.window; 26 import dsfml.audio; 27 import dsfml.system; 28 import dsfml.network; 29 } 30 31 /// Initialization of the external binding. 32 void initExternalBinding() 33 { 34 35 } 36 37 /// FloatVector -> Vector2f 38 Vector2f toNative(FloatVector vector) 39 { 40 return Vector2f(vector.x, vector.y); 41 } 42 43 /// UintVector -> Vector2u 44 Vector2u toNative(UintVector vector) 45 { 46 return Vector2u(vector.x, vector.y); 47 } 48 49 /// IntVector -> Vector2i 50 Vector2i toNative(IntVector vector) 51 { 52 return Vector2i(vector.x, vector.y); 53 } 54 55 /// Vector2f -> FloatVector 56 FloatVector fromNative(Vector2f vector) 57 { 58 return FloatVector(vector.x, vector.y); 59 } 60 61 /// Vector2u -> UintVector 62 UintVector fromNative(Vector2u vector) 63 { 64 return UintVector(vector.x, vector.y); 65 } 66 67 /// Vector2i -> IntVector 68 IntVector fromNative(Vector2i vector) 69 { 70 return IntVector(vector.x, vector.y); 71 } 72 73 /// Paint -> Color 74 Color toNative(Paint paint) 75 { 76 return Color(paint.r, paint.g, paint.b, paint.a); 77 } 78 79 /// Color -> Paint 80 Paint fromNative(Color color) 81 { 82 return Paint(color.r, color.g, color.b, color.a); 83 } 84 85 /// KeyboardKey -> Keyboard.Key 86 Keyboard.Key toNative(KeyboardKey key) 87 { 88 return cast(Keyboard.Key)key; 89 } 90 91 /// KeyboardKey -> Keyboard.Key 92 KeyboardKey fromNative(Keyboard.Key key) 93 { 94 return cast(KeyboardKey)key; 95 } 96 97 /// MouseButton -> Mouse.Button 98 Mouse.Button toNative(MouseButton button) 99 { 100 return cast(Mouse.Button)button; 101 } 102 103 /// Mouse.Button -> MouseButton 104 MouseButton fromNative(Mouse.Button button) 105 { 106 return cast(MouseButton)button; 107 } 108 109 /// IExternalDrawableComponent 110 interface IExternalDrawableComponent 111 { 112 /// draw() 113 void draw(ExternalWindow window); 114 } 115 116 /// ExternalImage 117 final class ExternalImage : IExternalDrawableComponent 118 { 119 private: 120 /// _image 121 Image _image; 122 /// _texture 123 Texture _texture; 124 /// _sprite 125 Sprite _sprite; 126 127 public: 128 /// this() 129 this() 130 { 131 } 132 133 /// loadFromFile() 134 void loadFromFile(string path) 135 { 136 _image = new Image; 137 _image.loadFromFile(path); 138 _texture = new Texture; 139 _texture.loadFromImage(_image); 140 _texture.setSmooth(true); 141 _sprite = new Sprite(_texture); 142 } 143 144 @property 145 { 146 /// Gets bounds. 147 FloatVector bounds() 148 { 149 auto localBounds = _sprite.getLocalBounds(); 150 151 return FloatVector(localBounds.width, localBounds.height); 152 } 153 154 /// Gets size. 155 UintVector size() 156 { 157 return _image.getSize().fromNative(); 158 } 159 160 /// Gets position. 161 FloatVector position() 162 { 163 return _sprite.position.fromNative(); 164 } 165 166 /// Sets position. 167 void position(FloatVector newPosition) 168 { 169 _sprite.position = newPosition.toNative(); 170 } 171 172 /// Gets color. 173 Paint color() 174 { 175 return _sprite.color.fromNative(); 176 } 177 178 /// Sets color. 179 void color(Paint newColor) 180 { 181 _sprite.color = newColor.toNative(); 182 } 183 184 /// Gets scale. 185 FloatVector scale() 186 { 187 return _sprite.scale.fromNative(); 188 } 189 190 /// Sets scale. 191 void scale(FloatVector newScale) 192 { 193 _sprite.scale = newScale.toNative(); 194 } 195 } 196 197 /// draw() 198 void draw(ExternalWindow window) 199 { 200 window._window.draw(_sprite); 201 } 202 } 203 204 /// ExternalWindow. 205 final class ExternalWindow 206 { 207 private: 208 /// _window. 209 RenderWindow _window; 210 /// _fps. 211 uint _fps; 212 213 public: 214 @property 215 { 216 /// Gets isOpen. 217 bool isOpen() { return _window.isOpen(); } 218 219 /// Gets fps. 220 uint fps() { return _fps; } 221 222 /// Sets fps. 223 void fps(uint newFps) 224 { 225 _fps = newFps; 226 227 _window.setFramerateLimit(_fps); 228 } 229 230 bool canUpdate() 231 { 232 return true; 233 } 234 } 235 236 /// close() 237 void close() 238 { 239 _window.close(); 240 } 241 242 /// render() 243 void render() 244 { 245 _window.display(); 246 } 247 248 /// clear() 249 void clear(Paint paint) 250 { 251 _window.clear(paint.toNative()); 252 } 253 254 /// processEvents() 255 bool processEvents(ExternalEventManager eventManager) 256 { 257 Event e; 258 while(_window.pollEvent(e)) 259 { 260 auto res = _window.pollEvent(e); 261 262 switch (e.type) 263 { 264 case Event.EventType.Closed: 265 eventManager.fireEvent(cast(ExternalEventType)e.type); 266 return false; 267 268 case Event.EventType.Resized: 269 ExternalEventState._sizeEvent = cast(ExternalSizeEvent)e.size; 270 break; 271 272 case Event.EventType.TextEntered: 273 ExternalEventState._textEvent = cast(ExternalTextEvent)e.text; 274 break; 275 276 case Event.EventType.KeyPressed: 277 case Event.EventType.KeyReleased: 278 ExternalEventState._keyEvent = cast(ExternalKeyEvent)e.key; 279 break; 280 281 case Event.EventType.MouseWheelMoved: 282 ExternalEventState._mouseWheelEvent = cast(ExternalMouseWheelEvent)e.mouseWheel; 283 break; 284 285 case Event.EventType.MouseButtonPressed: 286 case Event.EventType.MouseButtonReleased: 287 ExternalEventState._mouseButtonEvent = cast(ExternalMouseButtonEvent)e.mouseButton; 288 break; 289 290 case Event.EventType.MouseMoved: 291 ExternalEventState._mouseMoveEvent = cast(ExternalMouseMoveEvent)e.mouseMove; 292 break; 293 294 case Event.EventType.JoystickButtonPressed: 295 case Event.EventType.JoystickButtonReleased: 296 ExternalEventState._joystickButtonEvent = cast(ExternalJoystickButtonEvent)e.joystickButton; 297 break; 298 299 case Event.EventType.JoystickMoved: 300 ExternalEventState._joystickMoveEvent = cast(ExternalJoystickMoveEvent)e.joystickMove; 301 break; 302 303 case Event.EventType.JoystickConnected: 304 case Event.EventType.JoystickDisconnected: 305 ExternalEventState._joystickConnectEvent = cast(ExternalJoystickConnectEvent)e.joystickConnect; 306 break; 307 308 default: break; 309 } 310 311 eventManager.fireEvent(cast(ExternalEventType)e.type); 312 } 313 314 return true; 315 } 316 317 static: 318 /// create() 319 ExternalWindow create(string title, size_t width, size_t height, bool fullScreen) 320 { 321 auto videoMode = VideoMode(cast(int)width, cast(int)height); 322 ContextSettings context; 323 context.antialiasingLevel = 100; 324 325 RenderWindow renderWindow; 326 if (fullScreen) 327 { 328 renderWindow = new RenderWindow(videoMode, title, (Window.Style.Fullscreen), context); 329 } 330 else 331 { 332 renderWindow = new RenderWindow(videoMode, title, (Window.Style.Titlebar | Window.Style.Close), context); 333 } 334 335 auto window = new ExternalWindow; 336 window._window = renderWindow; 337 return window; 338 } 339 } 340 341 /// ExternalRectangleShape 342 final class ExternalRectangleShape : IExternalDrawableComponent 343 { 344 private: 345 /// _rect 346 RectangleShape _rect; 347 348 public: 349 final: 350 /// this() 351 this(FloatVector size) 352 { 353 _rect = new RectangleShape(size.toNative()); 354 } 355 356 @property 357 { 358 /// Gets fillColor 359 Paint fillColor() 360 { 361 return _rect.fillColor.fromNative(); 362 } 363 364 /// Sets fillColor 365 void fillColor(Paint newColor) 366 { 367 _rect.fillColor = newColor.toNative(); 368 } 369 370 /// Gets position 371 FloatVector position() 372 { 373 return _rect.position.fromNative(); 374 } 375 376 /// Sets position 377 void position(FloatVector newPosition) 378 { 379 _rect.position = newPosition.toNative(); 380 } 381 } 382 383 /// draw() 384 void draw(ExternalWindow window) 385 { 386 window._window.draw(_rect); 387 } 388 } 389 390 /// ExternalText 391 final class ExternalText : IExternalDrawableComponent 392 { 393 private: 394 /// _text 395 Text _text; 396 397 public: 398 final: 399 /// this() 400 this() 401 { 402 _text = new Text(); 403 } 404 405 @property 406 { 407 /// Gets bounds. 408 FloatVector bounds() 409 { 410 auto localBounds = _text.getLocalBounds(); 411 412 return FloatVector(localBounds.width, localBounds.height); 413 } 414 415 /// Gets position. 416 FloatVector position() 417 { 418 return _text.position.fromNative(); 419 } 420 421 /// Sets position. 422 void position(FloatVector newPosition) 423 { 424 _text.position = newPosition.toNative(); 425 } 426 } 427 428 /// setFont() 429 void setFont(ExternalFont font) 430 { 431 _text.setFont(font._font); 432 } 433 434 /// setString() 435 void setString(dstring text) 436 { 437 _text.setString(text); 438 } 439 440 /// setCharacterSize() 441 void setCharacterSize(size_t characterSize) 442 { 443 _text.setCharacterSize(cast(uint)characterSize); 444 } 445 446 /// setColor() 447 void setColor(Paint newColor) 448 { 449 _text.setColor(newColor.toNative()); 450 } 451 452 /// draw() 453 void draw(ExternalWindow window) 454 { 455 window._window.draw(_text); 456 } 457 } 458 459 /// ExternalFont 460 final class ExternalFont 461 { 462 private: 463 /// _font 464 Font _font; 465 466 public: 467 final: 468 /// this() 469 this() 470 { 471 _font = new Font; 472 } 473 474 /// loadFromFile() 475 void loadFromFile(string path) 476 { 477 _font.loadFromFile(path); 478 } 479 } 480 481 /// ExternalMusic 482 final class ExternalMusic 483 { 484 private: 485 /// _music 486 Music _music; 487 488 public: 489 final: 490 /// this() 491 this() 492 { 493 _music = new Music(); 494 } 495 496 @property 497 { 498 /// Gets looping 499 bool looping() 500 { 501 return _music.isLooping; 502 } 503 504 /// Sets looping 505 void looping(bool isLooping) 506 { 507 _music.isLooping = isLooping; 508 } 509 } 510 511 /// openFromFile() 512 bool openFromFile(string music) 513 { 514 return _music.openFromFile(music); 515 } 516 517 /// play() 518 void play() 519 { 520 _music.play(); 521 } 522 523 /// pause() 524 void pause() 525 { 526 _music.pause(); 527 } 528 529 /// stop() 530 void stop() 531 { 532 _music.stop(); 533 } 534 } 535 536 /// quit() 537 void quit() 538 { 539 540 } 541 }