+++ /dev/null
-# This file is part of NIT (http://www.nitlanguage.org).
-#
-# Copyright 2012-2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Android support for MNit
-module android
-
-import android_app
-import android_opengles1
-import android_assets
+++ /dev/null
-# This file is part of NIT (http://www.nitlanguage.org).
-#
-# Copyright 2012-2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Impements the services of `mnit:app` using the API from the Android ndk
-module android_app is android_manifest_activity """
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:configChanges="orientation|keyboardHidden"
-"""
-
-import mnit
-import mnit::opengles1
-import ::android::game
-intrude import ::android::input_events
-
-in "C" `{
- #include <EGL/egl.h>
-
- extern EGLDisplay mnit_display;
- extern EGLSurface mnit_surface;
- extern EGLContext mnit_context;
- extern EGLConfig mnit_config;
- extern int32_t mnit_width;
- extern int32_t mnit_height;
-`}
-
-redef class App
- redef fun init_window
- do
- display = new Opengles1Display
-
- super
- end
-
- redef fun full_frame do if not paused then super
-
- redef fun generate_input do poll_looper 0
-
- redef fun native_input_key(event)
- do
- return input(event)
- end
-
- redef fun native_input_motion(event)
- do
- var ie = new AndroidMotionEvent(event)
- var handled = input(ie)
-
- if not handled then
- input ie.acting_pointer
- end
-
- return handled
- end
-end
+++ /dev/null
-# This file is part of NIT (http://www.nitlanguage.org).
-#
-# Copyright 2012-2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Implements the `mnit::assets` services with a wraper around the filesystem
-# API provided by the Android ndk.
-#
-# This module relies heavily on 3 C libraries:
-# * The Android ndk
-# * zlib (which is included in the Android ndk)
-# * libpng which must be provided by the Nit compilation framework
-module android_assets
-
-import mnit
-import android_app
-intrude import android::assets_and_resources
-intrude import android::load_image
-
-extern class AndroidAsset in "C" `{struct AAsset*`}
-
- fun read(count: Int): nullable String import String.as nullable, CString.to_s `{
- char *buffer = malloc(sizeof(char) * (count+1));
- int read = AAsset_read(self, buffer, count);
- if (read != count)
- return null_String();
- else
- {
- buffer[count] = '\0';
- return String_as_nullable(CString_to_s(buffer));
- }
- `}
-
- fun length: Int `{
- return AAsset_getLength(self);
- `}
-
- fun to_fd: Int `{
- off_t start;
- off_t length;
- int fd = AAsset_openFileDescriptor(self, &start, &length);
- return fd;
- `}
-
- fun close `{
- AAsset_close(self);
- `}
-end
-
-redef class App
- redef fun try_loading_asset(path)
- do
- # Load images with the Java API
- var ext = path.file_extension
- if ext == "png" or ext == "jpg" or ext == "jpeg" then
- jni_env.push_local_frame 4
-
- var bmp = asset_manager.bitmap(path)
- var buf = bmp.copy_pixels(true, true)
- var w2 = bmp.width.next_pow(2)
- var h2 = bmp.height.next_pow(2)
- var png = new Opengles1Image.from_data(buf.native_array, bmp.width, bmp.height, w2, h2, true)
-
- buf.destroy
- jni_env.pop_local_frame
- return png
- end
-
- var a = load_asset_from_apk(path)
- if a != null then
- if ext == "txt" then
- var len = a.length
- var txt = a.read(len)
- return txt
- end
- else
- print "didn't get asset {path}"
- end
-
- return null
- end
-
- protected fun load_asset_from_apk(path: String): nullable AndroidAsset import String.to_cstring, AndroidAsset.as nullable, native_app_glue `{
- struct android_app *native_app_glue = App_native_app_glue(self);
- struct AAsset* a = AAssetManager_open(native_app_glue->activity->assetManager, String_to_cstring(path), AASSET_MODE_BUFFER);
- if (a == NULL)
- {
- LOGW("nit d g a");
- return null_AndroidAsset();
- }
- else
- {
- return AndroidAsset_as_nullable(a);
- }
- `}
-end
-
-redef class Opengles1Image
- private new from_data(pixels: Pointer, width, height, width_pow2, height_pow2: Int, has_alpha: Bool) `{
- return mnit_opengles_load_image((const uint_least32_t *)pixels,
- width, height, width_pow2, height_pow2, has_alpha);
- `}
-end
+++ /dev/null
-# This file is part of NIT (http://www.nitlanguage.org).
-#
-# Copyright 2012-2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Adapts OpenGL ES 1.0 for use on Android by offering services to get
-# a handler to the native display and window.
-module android_opengles1 is ldflags "-lEGL -lGLESv1_CM"
-
-import android_app
-
-in "C" `{
- #include <android_native_app_glue.h>
-
- NativeWindowType mnit_window;
- EGLNativeDisplayType mnit_native_display = EGL_DEFAULT_DISPLAY;
-`}
-
-redef class Opengles1Display
- redef fun midway_init(format) import app_native_window `{
- mnit_window = Opengles1Display_app_native_window(self);
- if (ANativeWindow_setBuffersGeometry(mnit_window, 0, 0, (EGLint)format) != 0) {
- LOGW("Unable to ANativeWindow_setBuffersGeometry");
- }
- `}
-
- private fun app_native_window: ANativeWindow do return app.native_app_glue.window
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2011-2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Manages all assets usable by an Mnit app
-module assets
-
-import mnit_app
-import mnit::display
-
-# General asset
-interface MnitAsset
-end
-
-# An String is an asset, returned from a text file
-redef class String
- super MnitAsset
-end
-
-# An Image is an asset
-redef interface Image
- super MnitAsset
-end
-
-redef class App
- # Load a genereal asset from file name
- # Will find the file within the assets/ directory
- # Crashes if file not found
- fun load_asset( id: String ): MnitAsset
- do
- var asset = try_loading_asset( id )
- if asset == null then # error
- print_error "asset <{id}> could not be loaded."
- abort
- else
- return asset
- end
- end
-
- # Load an Image assets
- # Crashes if file not found or not an image
- fun load_image( id: String ): Image
- do
- var asset = load_asset( id )
- if asset isa Image then
- return asset
- else
- print_error "asset <{id}> is not an image."
- abort
- end
- end
-
- # Load an assets without error if not found
- fun try_loading_asset( id: String ): nullable MnitAsset is abstract
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2011-2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Defines abstract display classes
-module display
-
-import mnit::input
-
-# Any class with a size
-interface Sized
- fun width: Int is abstract
- fun height: Int is abstract
-end
-
-# General image class, will be specialized for each classes
-interface Image
- super Sized
-
- fun destroy is abstract
-
- # Scale this image when blit
- var scale: Float is abstract, writable
-
- # Use blending on this image?
- var blended: Bool is abstract, writable
-
- # Get another image from this one
- fun subimage( x, y, w, h: Int ): Image is abstract
-end
-
-# General class for everything drawable to
-# Is used by drawable images and display
-interface Drawable
- type I: Image
-
- # Call to prepare for drawing
- fun begin is abstract
-
- # Call when drawing is finished
- fun finish is abstract
-
- # Set viewport for drawing
- fun set_viewport( x, y, w, h: Int ) is abstract
-
- # Draw image on self, for top left position
- fun blit(image: I, x, y: Numeric) is abstract
-
- # Draw image on self, for top left position but scaled
- # the width and height of the target rectangle is specified
- fun blit_scaled(image: Image, x, y, w, h: Numeric)
- do
- var fx = x.to_f
- var fy = y.to_f
- var fx2 = fx + w.to_f
- var fy2 = fy + h.to_f
- blit_stretched(image, fx, fy, fx, fy2, fx2, fy2, fx2, fy)
- end
-
- # Draw image, centered at position
- fun blit_centered(image: I, x, y: Numeric) is abstract
-
- # Draw image, centered at position but rotated
- fun blit_rotated(image: I, x, y: Numeric, angle: Float) is abstract
-
- # Draw image, centered, rotated and scaled
- fun blit_rotated_scaled(image: I, x, y: Numeric, angle, scale: Float) is abstract
-
- # Draw image by specifying the positon of each image corners
- # Corners are in counter-clockwise order stating top left
- # a is top left, b is bottom left, c is bottom right and d is top right
- # ~~~raw
- # a-d
- # | |
- # b-c
- # ~~~
- fun blit_stretched(image: I, ax, ay, bx, by, cx, cy, dx, dy: Numeric)
- is abstract
-
- # Clear entire window with given color
- fun clear( r, g, b: Float ) is abstract
-end
-
-# General display class, is sized and drawable
-interface Display
- super Sized
- super Drawable
-end
-
-# General drawable display image
-interface DrawableImage
- super Drawable
- super Image
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Utility module used by the svg_to_png_and_nit tool. It is imported
-# by each generated modules.
-module image_set
-
-import assets
-
-# A set of images, look for sub-classes in projects using svg_to_png_and_nit
-abstract class ImageSet
-
- # Load images to fill this image set
- fun load_all(app: App) is abstract
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2011-2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Linux support for MNit
-module linux
-
-import linux_app
-import linux_opengles1
-import linux_assets
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2011-2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-module linux_app
-
-import mnit
-import sdl
-import linux_opengles1
-import ::linux
-
-in "C" `{
- #include <EGL/egl.h>
-`}
-
-redef class App
- redef fun setup
- do
- if "NIT_TESTING".environ == "true" then exit 0
- display = new Opengles1Display
-
- super
- end
-
- redef fun generate_input
- do
- var display = display
- assert display isa Opengles1Display
-
- for event in display.sdl_display.events do
- input event
- end
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2011-2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-module linux_assets
-
-import mnit
-import linux_app
-
-redef class App
- redef fun try_loading_asset( id )
- do
- var path = "{assets_dir}/{id}"
- if not path.file_exists then
- print_error "asset <{id}> does not exists."
- exit(1)
- abort
- else
- var ext = path.file_extension
- if ext == "png" or ext == "jpg" or ext == "jpeg" then
- return new Opengles1Image.from_file( path )
- else # load as text
- var f = new FileReader.open(path)
- var content = f.read_all
- f.close
-
- return content
- end
- end
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2011-2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-module linux_opengles1 is pkgconfig("x11")
-
-import mnit::opengles1
-
-import sdl
-
-in "C" `{
- NativeWindowType mnit_window;
- EGLNativeDisplayType mnit_native_display;
-
- SDL_Surface* mnit_sdl_surface;
-`}
-
-redef class Display
- fun wanted_width: Int do return 800
- fun wanted_height: Int do return 600
-end
-
-redef class Opengles1Display
-
- # display managing the window, events, fonts? and image loading?
- var sdl_display: SDLDisplay
-
- redef fun extern_init do
- sdl_display = new SDLDisplay( wanted_width, wanted_height )
- init_from_sdl( sdl_display )
- return super
- end
-
- fun init_from_sdl( sdl_display: SDLDisplay ): Bool `{
- mnit_sdl_surface = sdl_display;
-
- mnit_window = (NativeWindowType)XOpenDisplay(NULL);
- mnit_native_display = (EGLNativeDisplayType)mnit_window;
-
- if (!mnit_window)
- {
- fprintf(stderr, "ERROR: unable to get display!n");
- return 3;
- }
-
- SDL_SysWMinfo mnit_sys_info;
- SDL_VERSION(&mnit_sys_info.version);
- if(SDL_GetWMInfo(&mnit_sys_info) <= 0)
- {
- printf("Unable to get window handle");
- return 0;
- }
-
- mnit_window = (EGLNativeWindowType)mnit_sys_info.info.x11.window;
-
- return 0;
- `}
-
- redef fun close
- do
- super
-
- sdl_display.destroy
- end
-end
-
-redef extern class Opengles1Image
- new from_sdl_image( sdl_image: SDLImage ) `{
- return mnit_opengles_load_image( sdl_image->pixels,
- sdl_image->w, sdl_image->h,
- sdl_image->w, sdl_image->h, sdl_image->format->Amask );
- `}
-
- # using sdl
- new from_file( path: String ) import String.to_cstring `{
- SDL_Surface *sdl_image;
- struct mnit_opengles_Texture *opengles_image;
-
- sdl_image = IMG_Load( String_to_cstring( path ) );
- if ( !sdl_image ) {
- fprintf(stderr, "SDL failed to load image <%s>: %s\n", String_to_cstring(path), IMG_GetError());
- return NULL;
- } else {
- opengles_image = mnit_opengles_load_image( sdl_image->pixels,
- sdl_image->w, sdl_image->h,
- sdl_image->w, sdl_image->h, sdl_image->format->Amask );
- SDL_FreeSurface(sdl_image);
- return opengles_image;
- }
- `}
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2011-2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Multiplatform game framework for Nit
-module mnit
-
-import mnit_app
-import assets
-import numbers
-import mnit_fps
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2011-2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# General Mnit application structure
-module mnit_app
-
-import ::app
-import mnit::display
-
-# An App instance serves as base to every Mnit projects.
-#
-# This class is redefed by plateforme modules and so
-# App can be specialized directly in the user app.
-redef class App
- type D: Display
- type I: Image
-
- # Display to use by apps
- # Is null if the display is not available or not yet ready
- var display: nullable D = null is protected writable
-
- # Received quit order
- var quit: Bool = false is writable
-
- # App is visible? (vs minimized or in background)
- fun visible: Bool is abstract
-
- # Invoqued at each frame
- # Usually you want to redef frame_core instead of this
- fun full_frame
- do
- var display = self.display
- if display != null then
- display.begin
- frame_core( display )
- display.finish
- end
- end
-
- # Main frame method to redef
- # Is called between readying display and flipping it
- fun frame_core( display: D ) do end
-
- # Receive and deal with all inputs
- fun input( event: InputEvent ): Bool
- do
- return false
- end
-
- # Internal method to generate inputs
- protected fun generate_input
- do
- if "NIT_TESTING".environ == "true" then exit 0
- print "Compiled without platform"
- exit 1
- end
-
- # Main app loop
- # Usually you want to redef frame_core instead of this
- redef fun run
- do
- while not quit do
- generate_input
- full_frame
- end
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Frame-rate control for applications
-module mnit_fps
-
-import mnit_app
-private import realtime
-
-redef class App
- # Limit the frame-rate to a given frequency
- # This basically limits how much `frame_core` is called per second.
- # Zero (or a negative value) means no limit.
- #
- # Applications can modify this value even during the main-loop.
- var maximum_fps = 60.0 is writable
-
- # Current frame-rate
- # Updated each 5 seconds.
- var current_fps = 0.0
-
- redef fun full_frame
- do
- super
- limit_fps
- end
-
- # The clock for limit_fps
- private var clock = new Clock
-
- # Number of frames since the last deadline
- # Used tocompute `current_fps`.
- private var frame_count = 0
-
- # Deadline used to compute `current_fps`
- private var frame_count_deadline = 0.0
-
- # Check and sleep to maitain a frame-rate bellow `maximum_fps`
- # Also periodically uptate `current_fps`
- # Is automatically called at the end of `full_frame`.
- fun limit_fps
- do
- var t = clock.total
- if t >= frame_count_deadline then
- var cfps = frame_count.to_f / 5.0
- self.current_fps = cfps
- frame_count = 0
- frame_count_deadline = t + 5.0
- end
- frame_count += 1
-
- var mfps = maximum_fps
- if mfps <= 0.0 then return
- var lapse = clock.lapse
- var dt = lapse.to_f
- var target_dt = 1.0 / mfps
- if dt < target_dt then
- var sleep_t = target_dt - dt
- sleep_t.sleep
- clock.lapse
- end
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Injection of input events that are read frm a file.
-# This cloud be used to replay an execution of a mnit application to debug or to benchmark it.
-#
-# The input file is given through the environment variable `MNIT_READ_INPUT`
-#
-# In order to reproduce executions, the behavior of the application must be deterministic
-# for a given sequence of inputs.
-# The main source of differences in executions is caused by the `rand` function,
-# Set the environment variable `NIT_SRAND` to a value to force srand to be initialized with this value.
-#
-# The input event file is made of event descriptions, one event by line.
-#
-# ~~~raw
-# 10 click 10.0 20.0
-# 20 quit
-# ~~~
-#
-# The first field, an integer, is the delay (in frame count) since the previous event
-# 0 means the event is launched in the same frame that the previous one.
-#
-# The second field, a string, is the kind of the event.
-# Currently only `click` for PointerEvent and `quit` for QuitEvent are recognized.
-#
-# The following fields are the arguments that specific for each kind of event.
-#
-# * `quit` does not have arguments
-# * `click` has 2 float arguments: `PointerEvent::x` and `PointerEvent::y`
-module mnit_injected_input
-
-import mnit_app
-
-# Concrete event objects that are manually instantiated.
-# Most InputEvent are extern classes and specific to one platform.
-#
-# However, subclasses of this `DummyInputEvent` are genuine Nit
-# classes and can be instantiated, and more easily manipulated by the programmer.
-interface DummyInputEvent
- super InputEvent
-end
-
-# A concrete QuitEvent
-class DummyQuitEvent
- super DummyInputEvent
- super QuitEvent
- redef fun to_s do return "quit"
-end
-
-# A concrete PointerEvent
-class DummyPointerEvent
- super DummyInputEvent
- super PointerEvent
- redef var x: Float
- redef var y: Float
- redef fun pressed do return true
- redef fun to_s do return "click {x} {y}"
-end
-
-redef class App
- # The stream where injected inputs are read
- private var injected_input_stream: nullable Reader = null
-
- redef fun setup
- do
- var input = "MNIT_READ_INPUT".environ
- if input != "" then
- injected_input_stream = new FileReader.open(input)
- print "GET injected_input_stream {input}"
- end
-
- super
- end
-
- # Number of frames before the next injected input
- private var wait_next_input = 0
-
- # What is the input to inject when `wait_next_input` become 0
- private var next_input: nullable DummyInputEvent
-
- redef fun full_frame
- do
- if injected_input_stream != null then generate_injected_input
- super
- end
-
- # Internal method to generate injected input events
- # Is called before each frame
- # Return `true` is an input event was injexted
- fun generate_injected_input: Bool
- do
- var res = false
- loop
- if wait_next_input > 0 then
- wait_next_input -= 1
- return res
- end
- var n = next_input
- if n != null then
- print "INPUT {n}"
- res = true
- input(n)
- end
- var l = injected_input_stream.read_line
- if l == "" then
- print "END OF INPUTS"
- injected_input_stream.close
- injected_input_stream = null
- input(new DummyQuitEvent)
- return true
- end
- print "read {l}"
- var fs = l.split(" ")
- if fs.length < 2 then
- print "BAD EVENT SPEC {l}"
- res = true
- input(new DummyQuitEvent)
- end
- wait_next_input = fs[0].to_i
- if fs[1] == "click" then
- next_input = new DummyPointerEvent(fs[2].to_f, fs[3].to_f)
- else if fs[1] == "quit" then
- next_input = new DummyQuitEvent
- else
- print "UNKNOWN EVENT {fs[1]} (on {l})"
- res = true
- input(new DummyQuitEvent)
- return true
- end
- print "WAIT {wait_next_input} for {next_input.to_s}"
- end
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Dummy mnit platform for headless executions
-#
-# Extends `mnit_injected_input` so that the whole application is simulated.
-# This permits more debugging and benchmarking, even without screen (thinks
-# regression tests).
-#
-# Assets loading and display operations are executed with an empty body,
-# Except on frames that have some injected input events, in theses the
-# description of all blit operations are printed to screen.
-module mnit_null
-
-import mnit_app
-intrude import mnit_injected_input
-import mnit_fps
-import assets
-
-# Dummy display that just display nothing
-class NullDisplay
- super Display
- redef var width = 640
- redef var height = 480
- redef fun begin do end
- redef fun finish do end
- redef fun clear(r,g,b)
- do
- if not app.verbose then return
- print "CLEAR rgb({r};{g};{b})"
- end
- redef fun blit(image, x, y)
- do
- if not app.verbose then return
- print "BLIT {image} ({x},{y})"
- end
- redef fun blit_centered(image, x, y)
- do
- if not app.verbose then return
- print "BLIT {image} CENTERED ({x},{y})"
- end
- redef fun blit_rotated(image, x, y, a)
- do
- if not app.verbose then return
- print "BLIT {image} CENTERED ({x},{y}) ROTATED {a}"
- end
- redef fun blit_rotated_scaled(image, x, y, a, s)
- do
- if not app.verbose then return
- print "BLIT {image} CENTERED ({x},{y}) ROTATED {a} SCALED {s}"
- end
- redef fun blit_scaled(image, x, y, w, h)
- do
- if not app.verbose then return
- print "BLIT {image} ({x},{y}) -- ({x+w},{y+h})"
- end
- redef fun blit_stretched(image, ax, ay, bx, by, cx, cy, dx, dy)
- do
- if not app.verbose then return
- print "BLIT {image} ({ax},{ay}) -- ({bx},{by}) -- ({cx},{cy}) -- ({dx},{dy})"
- end
-end
-
-# Dummy image for a NullDisplay
-class NullImage
- super Image
- var path: String
- redef fun to_s do return path
- redef var scale = 1.0 is redef writable
- redef var width = 32
- redef var height = 32
-end
-
-redef class App
- redef fun setup
- do
- super
- display = new NullDisplay
- on_create
- end
-
- # Force the printing of blit operations
- # So traces of execution can be generated
- # Managed by `generate_injected_input`
- private var verbose = false
-
- redef fun limit_fps do return
-
- redef fun generate_injected_input
- do
- var res = super
- verbose = res
- return res
- end
- redef fun generate_input
- do
- # An implementation is required but to avoid infinite loops
- # we just `quit` when the stream is closed.
- if injected_input_stream == null then
- print "END OF INPUT"
- quit = true
- end
- end
-
- redef fun try_loading_asset(path)
- do
- print "LOAD {path}"
- return new NullImage(path)
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Helper services to draw numbers on screen
-module numbers
-
-import assets
-
-# A set of images to draw numbers
-class NumberImages
-
- # Images from 0 to 9
- var imgs: Array[Image]
-end
-
-redef class App
- # Load a `NumberImages` from the assets
- fun load_numbers(path: String): NumberImages
- do
- var imgs = new Array[Image]
- for d in [0..9] do imgs.add(load_image(path.replace("#", d.to_s)))
- return new NumberImages(imgs)
- end
-end
-
-redef class Display
- fun blit_number(imgs: NumberImages, number: Int, x, y: Int, centered: nullable Bool)
- do
- var str = number.to_s
-
- if centered == true then
- var w = 0
- for c in str.chars do
- var d = c.code_point-'0'.code_point
- var img = imgs.imgs[d]
- w += (img.width.to_f * img.scale).to_i
- end
- x -= w / 2
- var img = imgs.imgs.first
- y -= (img.width.to_f * img.scale).to_i / 2
- end
-
- for c in str.chars do
- var d = c.code_point-'0'.code_point
- assert d >= 0 and d <= 9
- var img = imgs.imgs[d]
- blit(img, x, y)
- x += (img.width.to_f * img.scale).to_i
- end
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2011-2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# OpenGL ES1 general support (most of it)
-module opengles1 is pkgconfig("glesv1_cm", "egl")
-
-import mnit::display
-
-in "C header" `{
- #include <EGL/egl.h>
- #include <GLES/gl.h>
-
- EGLDisplay mnit_display;
- EGLSurface mnit_surface;
- EGLContext mnit_context;
- EGLConfig mnit_config;
- int32_t mnit_width;
- int32_t mnit_height;
-
- struct mnit_opengles_Texture {
- GLuint texture;
-
- /* offsets on source texture */
- float src_xo, src_yo, src_xi, src_yi;
-
- /* destination width and height */
- int width, height;
-
- /* may vary depending on scaling */
- int center_x, center_y;
-
- float scale;
- int blended;
- };
-
- struct mnit_opengles_DrawableTexture {
- struct mnit_opengles_Texture super;
- GLuint fbo;
- GLuint depth;
- GLuint color;
- };
-
- GLenum mnit_opengles_error_code;
-
- struct mnit_opengles_Texture *mnit_opengles_load_image(
- const uint_least32_t *pixels, int width, int height,
- int width_pow2, int height_pow2, int has_alpha);
-`}
-
-in "C" `{
- extern NativeWindowType mnit_window;
- extern EGLNativeDisplayType mnit_native_display;
-
- GLfloat mnit_opengles_vertices[6][3] =
- {
- {0.0f, 1.0f, 0.0f},
- {1.0f, 1.0f, 0.0f},
- {0.0f, 0.0f, 0.0f},
- {1.0f, 0.0f, 0.0f},
- };
- GLfloat mnit_opengles_texture[6][2] =
- {
- {0.0f, 0.0f},
- {0.0f, 1.0f},
- {1.0f, 1.0f},
- {0.0f, 0.0f},
- {1.0f, 1.0f},
- {1.0f, 0.0f}
- };
-
- struct mnit_opengles_Texture *mnit_opengles_load_image(
- const uint_least32_t *pixels, int width, int height,
- int width_pow2, int height_pow2, int has_alpha)
- {
- struct mnit_opengles_Texture *image = malloc(sizeof(struct mnit_opengles_Texture));
- int format = has_alpha? GL_RGBA: GL_RGB;
-
- image->width = width;
- image->height = height;
- image->center_x = width/2;
- image->center_y = height/2;
- image->scale = 1.0f;
- image->blended = has_alpha;
-
- image->src_xo = 0;
- image->src_yo = 0;
- image->src_xi = ((float)width)/width_pow2;
- image->src_yi = ((float)height)/height_pow2;
-
- if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- PRINT_ERROR("error loading image after malloc: %i", mnit_opengles_error_code);
- }
-
- glGenTextures(1, &image->texture);
-
- if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- PRINT_ERROR("error loading image after glGenTextures: %i", mnit_opengles_error_code);
- }
-
- glBindTexture(GL_TEXTURE_2D, image->texture);
-
- if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- PRINT_ERROR("error loading image glBindTexture: %i", mnit_opengles_error_code);
- }
-
- glTexImage2D( GL_TEXTURE_2D, 0, format, width_pow2, height_pow2,
- 0, format, GL_UNSIGNED_BYTE, (GLvoid*)pixels);
-
- if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- PRINT_ERROR("error loading image after glTexImage2D: %i", mnit_opengles_error_code);
- }
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- PRINT_ERROR("error loading image after gtTexParameter: %i", mnit_opengles_error_code);
- }
-
- return image;
- }
-`}
-
-# OpenGL ES1 display
-# Uses 3d hardware optimization
-class Opengles1Display
- super Display
-
- redef type I: Opengles1Image
-
- init do extern_init
- fun midway_init( format: Int ) do end
- fun extern_init: Bool import midway_init `{
- /* initialize OpenGL ES and EGL */
- const EGLint attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_BLUE_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_RED_SIZE, 8,
- EGL_NONE
- };
- EGLint w, h, format;
- EGLint numConfigs;
- EGLConfig config;
- EGLSurface surface;
- EGLContext context;
-
- EGLDisplay display = eglGetDisplay(mnit_native_display);
- if ( display == EGL_NO_DISPLAY) {
- PRINT_ERROR("Unable to eglGetDisplay");
- return -1;
- }
-
- if ( eglInitialize(display, 0, 0) == EGL_FALSE) {
- PRINT_ERROR("Unable to eglInitialize");
- return -1;
- }
-
- if ( eglChooseConfig(display, attribs, &config, 1, &numConfigs) == EGL_FALSE) {
- PRINT_ERROR("Unable to eglChooseConfig");
- return -1;
- }
-
- if ( numConfigs == 0 ) {
- PRINT_ERROR("No configs available for egl");
- return -1;
- }
-
- if ( eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format) == EGL_FALSE) {
- PRINT_ERROR("Unable to eglGetConfigAttrib");
- return -1;
- }
-
- /* Used by Android to set buffer geometry */
- Opengles1Display_midway_init(self, format);
-
- surface = eglCreateWindowSurface(display, config, mnit_window, NULL);
- context = eglCreateContext(display, config, NULL, NULL);
-
- if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
- PRINT_ERROR("Unable to eglMakeCurrent");
- return -1;
- }
-
- eglQuerySurface(display, surface, EGL_WIDTH, &w);
- eglQuerySurface(display, surface, EGL_HEIGHT, &h);
-
- mnit_display = display;
- mnit_context = context;
- mnit_surface = surface;
- mnit_config = config;
- mnit_width = w;
- mnit_height = h;
-
- glViewport(0, 0, mnit_width, mnit_height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrthof(0.0f, w, h, 0.0f, 0.0f, 1.0f);
- glMatrixMode(GL_MODELVIEW);
-
- glFrontFace( GL_CW );
-
- return 0;
- `}
-
- fun close `{
- if ( mnit_display != EGL_NO_DISPLAY) {
- eglMakeCurrent( mnit_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if ( mnit_context != EGL_NO_CONTEXT) {
- eglDestroyContext( mnit_display, mnit_context );
- }
- if ( mnit_surface != EGL_NO_SURFACE) {
- eglDestroySurface( mnit_display, mnit_surface );
- }
- eglTerminate( mnit_display);
- }
- mnit_display = EGL_NO_DISPLAY;
- mnit_context = EGL_NO_CONTEXT;
- mnit_surface = EGL_NO_SURFACE;
- `}
-
- redef fun begin `{
- glClear(GL_COLOR_BUFFER_BIT);
- glLoadIdentity();
- `}
-
- redef fun width: Int `{
- return mnit_width;
- `}
- redef fun height: Int `{
- return mnit_height;
- `}
-
- redef fun finish `{
- eglSwapBuffers( mnit_display, mnit_surface );
- `}
-
- redef fun set_viewport( x, y, w, h ) `{
- glLoadIdentity();
- glViewport(0,0, mnit_width, mnit_height );
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrthof(x, x+w, y+h, y, 0.0f, 1.0f);
- glMatrixMode(GL_MODELVIEW);
- glFrontFace( GL_CW );
- `}
-
- redef fun blit(image, x, y) do native_blit(image, x.to_f, y.to_f)
-
- private fun native_blit(image: Opengles1Image, x, y: Float) `{
- GLfloat texture_coord[4][2] =
- {
- {image->src_xo, image->src_yi},
- {image->src_xi, image->src_yi},
- {image->src_xo, image->src_yo},
- {image->src_xi, image->src_yo}
- };
-
- glLoadIdentity();
-
- glBindTexture(GL_TEXTURE_2D, image->texture);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTranslatef( x, y, 0.0f );
- glScalef( image->width*image->scale, image->height*image->scale, 1.0f );
-
- if ( image->blended ) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- glEnable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
-
- glVertexPointer(3, GL_FLOAT, 0, mnit_opengles_vertices);
- glTexCoordPointer(2, GL_FLOAT, 0, texture_coord );
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- if ( image->blended ) glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-
- if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- PRINT_ERROR("error drawing: %i", mnit_opengles_error_code);
- }
- `}
-
- redef fun blit_centered(img, x, y)
- do
- x = x.sub(img.center_x)
- y = y.sub(img.center_y)
- blit(img, x, y)
- end
-
- redef fun blit_rotated(image, x, y, angle) do native_blit_rotated(image, x.to_f, y.to_f, angle)
-
- private fun native_blit_rotated(image: Opengles1Image, x, y, angle: Float) `{
- GLfloat texture_coord[4][2] =
- {
- {image->src_xo, image->src_yi},
- {image->src_xi, image->src_yi},
- {image->src_xo, image->src_yo},
- {image->src_xi, image->src_yo}
- };
-
- glLoadIdentity();
-
- glBindTexture(GL_TEXTURE_2D, image->texture);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTranslatef( x, y, 0.0f );
- glRotatef( angle*180.0f/3.14156f, 0, 0, 1.0f );
- glTranslatef( image->width*image->scale/-2, image->height*image->scale/-2, 0.0f );
- glScalef( image->width*image->scale, image->height*image->scale, 1.0f );
- if ( image->blended ) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
- glEnable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
-
- glVertexPointer(3, GL_FLOAT, 0, mnit_opengles_vertices);
- glTexCoordPointer(2, GL_FLOAT, 0, texture_coord );
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- if ( image->blended ) glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-
- if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- PRINT_ERROR("error drawing: %i", mnit_opengles_error_code);
- }
- `}
-
- # a = top left, b = bottom left, c = bottom right, d = top right
- redef fun blit_stretched(image, ax, ay, bx, by, cx, cy, dx, dy)
- do
- native_blit_stretched(image,
- ax.to_f, ay.to_f, bx.to_f, by.to_f,
- cx.to_f, cy.to_f, dx.to_f, dy.to_f)
- end
-
- private fun native_blit_stretched(image: I, ax, ay, bx, by, cx, cy, dx, dy: Float) `{
- GLfloat texture_coord[4][2] =
- {
- {image->src_xo, image->src_yi},
- {image->src_xi, image->src_yi},
- {image->src_xo, image->src_yo},
- {image->src_xi, image->src_yo}
- };
-
- GLfloat mnit_opengles_vertices_stretched[6][3] =
- {
- {bx, by, 0.0f},
- {cx, cy, 0.0f},
- {ax, ay, 0.0f},
- {dx, dy, 0.0f},
- };
-
- glLoadIdentity();
-
- glBindTexture(GL_TEXTURE_2D, image->texture);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- if ( image->blended ) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- glEnable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
-
- glVertexPointer(3, GL_FLOAT, 0, mnit_opengles_vertices_stretched);
- glTexCoordPointer(2, GL_FLOAT, 0, texture_coord );
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- if ( image->blended ) glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-
- if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- PRINT_ERROR("error drawing: %i", mnit_opengles_error_code);
- }
- `}
-
- redef fun clear( r, g, b: Float ) `{
- glClearColor( r, g, b, 1.0 );
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- `}
-
- fun clear_alpha( r, g, b, a: Float ) `{
- glClearColor( r, g, b, a );
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- `}
-
- # Set the current color applied to all drawing
- #
- # require: r, g, b, a in [0.0 .. 1.0]
- fun color(r, g, b, a: Float) `{ glColor4f(r, g, b, a); `}
-
- # Reset the current color to opaque white
- fun reset_color `{ glColor4f(1.0f, 1.0f, 1.0f, 1.0f); `}
-end
-
-extern class Opengles1Image in "C" `{struct mnit_opengles_Texture *`}
- super Image
-
- redef fun destroy `{ free( self ); `}
-
- redef fun width: Int `{ return self->width; `}
- redef fun height: Int `{ return self->height; `}
-
- fun center_x: Int `{ return self->center_x; `}
- fun center_y: Int `{ return self->center_y; `}
-
- redef fun scale=( v: Float ) `{
- self->scale = v;
- self->center_x = v*self->width/2;
- self->center_y = v*self->height/2;
- `}
- redef fun scale: Float `{ return self->scale; `}
-
- redef fun blended=( v: Bool ) `{ self->blended = v; `}
- redef fun blended: Bool `{ return self->blended; `}
-
- # inherits scale and blend from source
- redef fun subimage( x, y, w, h: Int ): Image import Opengles1Image.as( Image ) `{
- struct mnit_opengles_Texture* image =
- malloc( sizeof( struct mnit_opengles_Texture ) );
-
- image->texture = self->texture;
- image->width = w;
- image->height = h;
- image->center_x = self->scale*w/2;
- image->center_y = self->scale*h/2;
- image->scale = self->scale;
- image->blended = self->blended;
-
- float r_dx = self->src_xi - self->src_xo;
- float r_dy = self->src_yi - self->src_yo;
- image->src_xo = self->src_xo + ((float)x)/self->width*r_dx;
- image->src_yo = self->src_yo + ((float)y)/self->height*r_dy;
- image->src_xi = self->src_xo + ((float)x+w)/self->width*r_dx;
- image->src_yi = self->src_yo + ((float)y+h)/self->height*r_dy;
-
- return Opengles1Image_as_Image( image );
- `}
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Manage images that are tileset or glyphset (for bitmap fonts)
-module tileset
-
-import mnit::display
-
-# Efficiently retrieve tiles in a big image
-class TileSet
- # The image containing the tileset
- var image: Image
-
- # The witdh of a tile
- var width: Int
-
- # The height of a tile
- var height: Int
-
- init
- do
- self.nb_cols = image.width / width
- self.nb_rows = image.height / height
-
- for j in [0..nb_rows[ do
- for i in [0..nb_cols[ do
- subimages.add image.subimage(i*width,j*height,width,height)
- end
- end
- end
-
- # The number of columns of tiles in the image
- var nb_cols: Int is noinit
-
- # The number of rows of tiles in the image
- var nb_rows: Int is noinit
-
- # Cache for images of tiles
- var subimages = new Array[Image]
-
- # The subimage of given tile
- # Aborts if x or y are out of bound
- fun [](x,y: Int): Image
- do
- assert x >= 0 and x < nb_cols and y >= 0 and y <= nb_rows else print "{x}x{y}<?{nb_cols}x{nb_rows}"
- var idx = x + y * nb_cols
- return subimages[idx]
- end
-end
-
-# A monospace bitmap font where glyphs are stored in a tileset
-class TileSetFont
- super TileSet
-
- # Each character in the image
- # in left->right, then top->bottom order
- # Use space (' ') for holes in the tileset
- var chars: String
-
- # Additional space to insert horizontally between characters
- # A negative value will display tile overlapped
- var hspace: Numeric = 0.0 is writable
-
- # Additional space to insert vertically between characters
- # A negative value will display tile overlapped
- var vspace: Numeric = 0.0 is writable
-
- # The glyph (tile) associated to the character `c` according to `chars`
- # Returns null if `c` is not in `chars`
- fun char(c: Char): nullable Image
- do
- var i = chars.index_of(c)
- if i == -1 then return null
- return subimages[i]
- end
-
- # Distance between the beginning of a letter tile and the beginning of the next letter tile
- fun advance: Numeric do return width.add(hspace)
-
- # Distance between the beginning and the end of the longest line of `text`
- fun text_width(text: String): Numeric
- do
- var lines = text.split('\n')
- if lines.is_empty then return 0
-
- var longest = 0
- for line in lines do longest = longest.max(line.length)
-
- return longest.mul(advance)
- end
-
- # Distance between the top of the first line to the bottom of the last line in `text`
- fun text_height(text: Text): Numeric
- do
- if text.is_empty then return 0
-
- var n_lines = text.chars.count('\n')
- return (n_lines+1).mul(height.add(vspace)).sub(vspace)
- end
-end
-
-redef class Display
- # Blit the text using a monospace bitmap font
- # '\n' are rendered as carriage return
- fun text(text: String, font: TileSetFont, x, y: Numeric)
- do
- x = x.to_f
- var cx = x
- var cy = y.to_f
- var sw = font.width.to_f + font.hspace.to_f
- var sh = font.height.to_f + font.vspace.to_f
- for c in text.chars do
- if c == '\n' then
- cx = x
- cy += sh
- continue
- end
- if c == ' ' then
- cx += sw
- continue
- end
- var image = font.char(c)
- if image != null then
- blit(image, cx, cy)
- end
- cx += sw
- end
- end
-end