mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-23 19:03:27 +08:00
examples: Added initial examples infrastructure.
This commit is contained in:
parent
2f6e34d2d0
commit
5339b4458d
183
build-scripts/build-web-examples.pl
Executable file
183
build-scripts/build-web-examples.pl
Executable file
@ -0,0 +1,183 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
|
||||||
|
# Simple DirectMedia Layer
|
||||||
|
# Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
#
|
||||||
|
# This software is provided 'as-is', without any express or implied
|
||||||
|
# warranty. In no event will the authors be held liable for any damages
|
||||||
|
# arising from the use of this software.
|
||||||
|
#
|
||||||
|
# Permission is granted to anyone to use this software for any purpose,
|
||||||
|
# including commercial applications, and to alter it and redistribute it
|
||||||
|
# freely, subject to the following restrictions:
|
||||||
|
#
|
||||||
|
# 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
# claim that you wrote the original software. If you use this software
|
||||||
|
# in a product, an acknowledgment in the product documentation would be
|
||||||
|
# appreciated but is not required.
|
||||||
|
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
# misrepresented as being the original software.
|
||||||
|
# 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use File::Basename;
|
||||||
|
use Cwd qw(abs_path);
|
||||||
|
use IPC::Open2;
|
||||||
|
|
||||||
|
my $examples_dir = abs_path(dirname(__FILE__) . "/../examples");
|
||||||
|
my $project = undef;
|
||||||
|
my $emsdk_dir = undef;
|
||||||
|
my $compile_dir = undef;
|
||||||
|
my $output_dir = undef;
|
||||||
|
|
||||||
|
sub usage {
|
||||||
|
die("USAGE: $0 <project_name> <emsdk_dir> <compiler_output_directory> <html_output_directory>\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub do_system {
|
||||||
|
my $cmd = shift;
|
||||||
|
$cmd = "exec /usr/bin/bash -c \"$cmd\"";
|
||||||
|
print("$cmd\n");
|
||||||
|
return system($cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub do_mkdir {
|
||||||
|
my $d = shift;
|
||||||
|
if ( ! -d $d ) {
|
||||||
|
print("mkdir '$d'\n");
|
||||||
|
mkdir($d) or die("Couldn't mkdir('$d'): $!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub build_latest {
|
||||||
|
# Try to build just the latest without re-running cmake, since that is SLOW.
|
||||||
|
print("Building latest version of $project ...\n");
|
||||||
|
if (do_system("EMSDK_QUIET=1 source '$emsdk_dir/emsdk_env.sh' && cd '$compile_dir' && ninja") != 0) {
|
||||||
|
# Build failed? Try nuking the build dir and running CMake from scratch.
|
||||||
|
print("\n\nBuilding latest version of $project FROM SCRATCH ...\n");
|
||||||
|
if (do_system("EMSDK_QUIET=1 source '$emsdk_dir/emsdk_env.sh' && rm -rf '$compile_dir' && mkdir '$compile_dir' && cd '$compile_dir' && emcmake cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .. && ninja") != 0) {
|
||||||
|
die("Failed to build latest version of $project!\n"); # oh well.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub handle_example_dir {
|
||||||
|
my $category = shift;
|
||||||
|
my $example = shift;
|
||||||
|
|
||||||
|
my @files = ();
|
||||||
|
my $files_str = '';
|
||||||
|
opendir(my $dh, "$examples_dir/$category/$example") or die("Couldn't opendir '$examples_dir/$category/$example': $!\n");
|
||||||
|
my $spc = '';
|
||||||
|
while (readdir($dh)) {
|
||||||
|
next if not /\.c\Z/; # only care about .c files.
|
||||||
|
my $path = "$examples_dir/$category/$example/$_";
|
||||||
|
next if not -f $path; # only care about files.
|
||||||
|
push @files, $path;
|
||||||
|
$files_str .= "$spc$path";
|
||||||
|
$spc = ' ';
|
||||||
|
}
|
||||||
|
closedir($dh);
|
||||||
|
|
||||||
|
my $dst = "$output_dir/$category/$example";
|
||||||
|
|
||||||
|
do_mkdir($dst);
|
||||||
|
print("Building $category/$example ...\n");
|
||||||
|
|
||||||
|
# !!! FIXME: hardcoded SDL3 references, need to fix this for satellite libraries and SDL2.
|
||||||
|
do_system("EMSDK_QUIET=1 source '$emsdk_dir/emsdk_env.sh' && emcc -s USE_SDL=0 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=1gb -s ASSERTIONS=0 -o '$dst/index.js' '-I$examples_dir/../include' $files_str '$compile_dir/libSDL3.a'") == 0
|
||||||
|
or die("Failed to build $category/$example!\n");
|
||||||
|
|
||||||
|
my $highlight_cmd = "highlight '--outdir=$dst' --style-outfile=highlight.css --fragment --stdout --syntax=c '--plug-in=$examples_dir/highlight-plugin.lua'";
|
||||||
|
print("$highlight_cmd\n");
|
||||||
|
my $pid = open2(my $child_out, my $child_in, $highlight_cmd);
|
||||||
|
|
||||||
|
my $htmlified_source_code = '';
|
||||||
|
foreach (@files) {
|
||||||
|
my $path = $_;
|
||||||
|
open my $srccode, '<', $path or die("Couldn't open '$path': $!\n");
|
||||||
|
my $fname = "$path";
|
||||||
|
$fname =~ s/\A.*\///;
|
||||||
|
print $child_in "/* $fname ... */\n\n";
|
||||||
|
while (<$srccode>) {
|
||||||
|
print $child_in $_;
|
||||||
|
}
|
||||||
|
close($srccode);
|
||||||
|
}
|
||||||
|
|
||||||
|
close($child_in);
|
||||||
|
|
||||||
|
while (<$child_out>) {
|
||||||
|
$htmlified_source_code .= $_;
|
||||||
|
}
|
||||||
|
close($child_out);
|
||||||
|
|
||||||
|
waitpid($pid, 0);
|
||||||
|
|
||||||
|
|
||||||
|
my $html = '';
|
||||||
|
open my $htmltemplate, '<', "$examples_dir/template.html" or die("Couldn't open '$examples_dir/template.html': $!\n");
|
||||||
|
while (<$htmltemplate>) {
|
||||||
|
s/\@project_name\@/$project/g;
|
||||||
|
s/\@category_name\@/$category/g;
|
||||||
|
s/\@example_name\@/$example/g;
|
||||||
|
s/\@htmlified_source_code\@/$htmlified_source_code/g;
|
||||||
|
$html .= $_;
|
||||||
|
}
|
||||||
|
close($htmltemplate);
|
||||||
|
|
||||||
|
open my $htmloutput, '>', "$dst/index.html" or die("Couldn't open '$dst/index.html': $!\n");
|
||||||
|
print $htmloutput $html;
|
||||||
|
close($htmloutput);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub handle_category_dir {
|
||||||
|
my $category = shift;
|
||||||
|
|
||||||
|
do_mkdir("$output_dir/$category");
|
||||||
|
|
||||||
|
opendir(my $dh, "$examples_dir/$category") or die("Couldn't opendir '$examples_dir/$category': $!\n");
|
||||||
|
|
||||||
|
while (readdir($dh)) {
|
||||||
|
next if ($_ eq '.') || ($_ eq '..'); # obviously skip current and parent entries.
|
||||||
|
next if not -d "$examples_dir/$category/$_"; # only care about subdirectories.
|
||||||
|
handle_example_dir($category, $_);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir($dh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Mainline!
|
||||||
|
|
||||||
|
foreach (@ARGV) {
|
||||||
|
$project = $_, next if not defined $project;
|
||||||
|
$emsdk_dir = $_, next if not defined $emsdk_dir;
|
||||||
|
$compile_dir = $_, next if not defined $compile_dir;
|
||||||
|
$output_dir = $_, next if not defined $output_dir;
|
||||||
|
usage(); # too many arguments.
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() if not defined $output_dir;
|
||||||
|
|
||||||
|
build_latest();
|
||||||
|
|
||||||
|
do_mkdir($output_dir);
|
||||||
|
|
||||||
|
print("Examples dir: $examples_dir\n");
|
||||||
|
|
||||||
|
opendir(my $dh, $examples_dir) or die("Couldn't opendir '$examples_dir': $!\n");
|
||||||
|
|
||||||
|
while (readdir($dh)) {
|
||||||
|
next if ($_ eq '.') || ($_ eq '..'); # obviously skip current and parent entries.
|
||||||
|
next if not -d "$examples_dir/$_"; # only care about subdirectories.
|
||||||
|
handle_category_dir($_);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir($dh);
|
||||||
|
|
||||||
|
exit(0); # success!
|
||||||
|
|
67
examples/README.md
Normal file
67
examples/README.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# Examples
|
||||||
|
|
||||||
|
## What is this?
|
||||||
|
|
||||||
|
In here are a collection of standalone SDL application examples. Unless
|
||||||
|
otherwise stated, they should work on all supported platforms out of the box.
|
||||||
|
If they don't [please file a bug to let us know](https://github.com/libsdl-org/SDL/issues/new).
|
||||||
|
|
||||||
|
|
||||||
|
## What is this SDL_AppIterate thing?
|
||||||
|
|
||||||
|
SDL can optionally build apps as a collection of callbacks instead of the
|
||||||
|
usual program structure that starts and ends in a function called `main`.
|
||||||
|
The examples use this format for two reasons.
|
||||||
|
|
||||||
|
First, it allows the examples to work when built as web applications without
|
||||||
|
a pile of ugly `#ifdef`s, and all of these examples are published on the web
|
||||||
|
at [examples.libsdl.org](https://examples.libsdl.org/), so you can easily see
|
||||||
|
them in action.
|
||||||
|
|
||||||
|
Second, it's example code! The callbacks let us cleanly break the program up
|
||||||
|
into the four logical pieces most apps care about:
|
||||||
|
|
||||||
|
- Program startup
|
||||||
|
- Event handling
|
||||||
|
- What the program actually does in a single frame
|
||||||
|
- Program shutdown
|
||||||
|
|
||||||
|
A detailed technical explanation of these callbacks is in
|
||||||
|
docs/README-main-functions.md (or view that page on the web on
|
||||||
|
[the wiki](https://wiki.libsdl.org/SDL3/README/main-functions#main-callbacks-in-sdl3).
|
||||||
|
|
||||||
|
|
||||||
|
## I would like to build and run these examples myself.
|
||||||
|
|
||||||
|
When you build SDL with CMake, you can add `-DSDL_BUILD_EXAMPLES=On` to the
|
||||||
|
CMake command line. When you build SDL, these examples will be built with it.
|
||||||
|
|
||||||
|
But most of these can just be built as a single .c file, as long as you point
|
||||||
|
your compiler at SDL3's headers and link against SDL.
|
||||||
|
|
||||||
|
|
||||||
|
## What is the license on the example code? Can I paste this into my project?
|
||||||
|
|
||||||
|
All code in the examples directory is considered public domain! You can do
|
||||||
|
anything you like with it, including copy/paste it into your closed-source
|
||||||
|
project, sell it, and pretend you wrote it yourself. We do not require you to
|
||||||
|
give us credit for this code (but we always appreciate if you do!).
|
||||||
|
|
||||||
|
This is only true for the examples directory. The rest of SDL falls under the
|
||||||
|
[zlib license](https://github.com/libsdl-org/SDL/blob/main/LICENSE.txt).
|
||||||
|
|
||||||
|
|
||||||
|
## What is template.html and highlight-plugin.lua in this directory?
|
||||||
|
|
||||||
|
This is what [examples.libsdl.org](https://examples.libsdl.org/) uses when
|
||||||
|
generating the web versions of these example programs. You can ignore this,
|
||||||
|
unless you are improving it, in which case we definitely would love to hear
|
||||||
|
from you!
|
||||||
|
|
||||||
|
|
||||||
|
## What is template.c in this directory?
|
||||||
|
|
||||||
|
If writing new examples, this is the skeleton code we start from, to keep
|
||||||
|
everything consistent. You can ignore it.
|
||||||
|
|
||||||
|
|
77
examples/highlight-plugin.lua
Normal file
77
examples/highlight-plugin.lua
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
-- This code adapted from https://gitlab.com/saalen/highlight/-/wikis/Plug-Ins
|
||||||
|
|
||||||
|
-- first add a description of what the plug-in does
|
||||||
|
Description="Add wiki.libsdl.org reference links to HTML, LaTeX or RTF output"
|
||||||
|
|
||||||
|
-- define the plugin categories (ie. supported output formats; languages)
|
||||||
|
Categories = { "c", "c++" }
|
||||||
|
|
||||||
|
-- the syntaxUpdate function contains code related to syntax recognition
|
||||||
|
function syntaxUpdate(desc)
|
||||||
|
|
||||||
|
-- if the current file is not C/C++ file we exit
|
||||||
|
if desc~="C and C++" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- this function returns a qt-project reference link of the given token
|
||||||
|
function getURL(token)
|
||||||
|
-- generate the URL
|
||||||
|
url='https://wiki.libsdl.org/SDL3/'.. token
|
||||||
|
|
||||||
|
-- embed the URL in a hyperlink according to the output format
|
||||||
|
-- first HTML, then LaTeX and RTF
|
||||||
|
if (HL_OUTPUT== HL_FORMAT_HTML or HL_OUTPUT == HL_FORMAT_XHTML) then
|
||||||
|
return '<a class="hl" target="new" href="'
|
||||||
|
.. url .. '">'.. token .. '</a>'
|
||||||
|
elseif (HL_OUTPUT == HL_FORMAT_LATEX) then
|
||||||
|
return '\\href{'..url..'}{'..token..'}'
|
||||||
|
elseif (HL_OUTPUT == HL_FORMAT_RTF) then
|
||||||
|
return '{{\\field{\\*\\fldinst HYPERLINK "'
|
||||||
|
..url..'" }{\\fldrslt\\ul\\ulc0 '..token..'}}}'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- the Decorate function will be invoked for every recognized token
|
||||||
|
function Decorate(token, state)
|
||||||
|
|
||||||
|
-- we are only interested in keywords, preprocessor or default items
|
||||||
|
if (state ~= HL_STANDARD and state ~= HL_KEYWORD and
|
||||||
|
state ~=HL_PREPROC) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- SDL keywords start with SDL_
|
||||||
|
-- if this pattern applies to the token, we return the URL
|
||||||
|
-- if we return nothing, the token is outputted as is
|
||||||
|
if string.find(token, "SDL_")==1 then
|
||||||
|
return getURL(token)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- the themeUpdate function contains code related to the theme
|
||||||
|
function themeUpdate(desc)
|
||||||
|
-- the Injections table can be used to add style information to the theme
|
||||||
|
|
||||||
|
-- HTML: we add additional CSS style information to beautify hyperlinks,
|
||||||
|
-- they should have the same color as their surrounding tags
|
||||||
|
if (HL_OUTPUT == HL_FORMAT_HTML or HL_OUTPUT == HL_FORMAT_XHTML) then
|
||||||
|
Injections[#Injections+1]=
|
||||||
|
"a.hl, a.hl:visited {color:inherit;font-weight:inherit;text-decoration:none}"
|
||||||
|
|
||||||
|
-- LaTeX: hyperlinks require the hyperref package, so we add this here
|
||||||
|
-- the colorlinks and pdfborderstyle options remove ugly boxes in the output
|
||||||
|
elseif (HL_OUTPUT==HL_FORMAT_LATEX) then
|
||||||
|
Injections[#Injections+1]=
|
||||||
|
"\\usepackage[colorlinks=false, pdfborderstyle={/S/U/W 1}]{hyperref}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- let highlight load the chunks
|
||||||
|
Plugins={
|
||||||
|
{ Type="lang", Chunk=syntaxUpdate },
|
||||||
|
{ Type="theme", Chunk=themeUpdate },
|
||||||
|
}
|
||||||
|
|
80
examples/renderer/clear/renderer-clear.c
Normal file
80
examples/renderer/clear/renderer-clear.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* This example code creates an SDL window and renderer, and then clears the
|
||||||
|
* window to a different color every frame, so you'll effectively get a window
|
||||||
|
* that's smoothly fading between colors.
|
||||||
|
*
|
||||||
|
* This code is public domain. Feel free to use it for any purpose!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#include <SDL3/SDL_main.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* We will use this renderer to draw into this window every frame. */
|
||||||
|
static SDL_Window *window = NULL;
|
||||||
|
static SDL_Renderer *renderer = NULL;
|
||||||
|
|
||||||
|
/* the current red color we're clearing to. */
|
||||||
|
static Uint8 red = 0;
|
||||||
|
|
||||||
|
/* When fading up, this is 1, when fading down, it's -1. */
|
||||||
|
static int fade_direction = 1;
|
||||||
|
|
||||||
|
|
||||||
|
/* This function runs once at startup. */
|
||||||
|
int SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (SDL_CreateWindowAndRenderer("examples/renderer/clear", 640, 480, 0, &window, &renderer) == -1) {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window/renderer!", SDL_GetError(), NULL);
|
||||||
|
return SDL_APP_FAILURE;
|
||||||
|
}
|
||||||
|
SDL_SetRenderVSync(renderer, 1); /* try to show frames at the monitor refresh rate. */
|
||||||
|
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||||
|
int SDL_AppEvent(void *appstate, const SDL_Event *event)
|
||||||
|
{
|
||||||
|
if (event->type == SDL_EVENT_QUIT) {
|
||||||
|
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||||
|
}
|
||||||
|
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function runs once per frame, and is the heart of the program. */
|
||||||
|
int SDL_AppIterate(void *appstate)
|
||||||
|
{
|
||||||
|
/* since we're always fading red, we leave green and blue at zero.
|
||||||
|
alpha doesn't mean much here, so leave it at full (255, no transparency). */
|
||||||
|
SDL_SetRenderDrawColor(renderer, red, 0, 0, 255);
|
||||||
|
|
||||||
|
/* clear the window to the draw color. */
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
/* put the newly-cleared rendering on the screen. */
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
|
||||||
|
/* update the color for the next frame we will draw. */
|
||||||
|
if (fade_direction > 0) {
|
||||||
|
if (red == 255) {
|
||||||
|
fade_direction = -1;
|
||||||
|
} else {
|
||||||
|
red++;
|
||||||
|
}
|
||||||
|
} else if (fade_direction < 0) {
|
||||||
|
if (red == 0) {
|
||||||
|
fade_direction = 1;
|
||||||
|
} else {
|
||||||
|
red--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function runs once at shutdown. */
|
||||||
|
void SDL_AppQuit(void *appstate)
|
||||||
|
{
|
||||||
|
/* SDL will clean up the window/renderer for us. */
|
||||||
|
}
|
||||||
|
|
45
examples/template.c
Normal file
45
examples/template.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* This example code $WHAT_IT_DOES.
|
||||||
|
*
|
||||||
|
* This code is public domain. Feel free to use it for any purpose!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#include <SDL3/SDL_main.h>
|
||||||
|
|
||||||
|
/* We will use this renderer to draw into this window every frame. */
|
||||||
|
static SDL_Window *window = NULL;
|
||||||
|
static SDL_Renderer *renderer = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/* This function runs once at startup. */
|
||||||
|
int SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (SDL_CreateWindowAndRenderer("examples/renderer/clear", 640, 480, 0, &window, &renderer) == -1) {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window/renderer!", SDL_GetError(), NULL);
|
||||||
|
return SDL_APP_FAILURE;
|
||||||
|
}
|
||||||
|
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||||
|
int SDL_AppEvent(void *appstate, const SDL_Event *event)
|
||||||
|
{
|
||||||
|
if (event->type == SDL_EVENT_QUIT) {
|
||||||
|
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||||
|
}
|
||||||
|
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function runs once per frame, and is the heart of the program. */
|
||||||
|
int SDL_AppIterate(void *appstate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function runs once at shutdown. */
|
||||||
|
void SDL_AppQuit(void *appstate)
|
||||||
|
{
|
||||||
|
/* SDL will clean up the window/renderer for us. */
|
||||||
|
}
|
||||||
|
|
117
examples/template.html
Normal file
117
examples/template.html
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-us">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>@project_name@ Example: @category_name@/@example_name@</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: arial;
|
||||||
|
margin: 0;
|
||||||
|
padding: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||||
|
div.emscripten { text-align: center; }
|
||||||
|
div.emscripten_border { border: 1px solid black; }
|
||||||
|
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||||
|
canvas.emscripten { border: 0px none; background-color: black; }
|
||||||
|
|
||||||
|
@-webkit-keyframes rotation {
|
||||||
|
from {-webkit-transform: rotate(0deg);}
|
||||||
|
to {-webkit-transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
@-moz-keyframes rotation {
|
||||||
|
from {-moz-transform: rotate(0deg);}
|
||||||
|
to {-moz-transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
@-o-keyframes rotation {
|
||||||
|
from {-o-transform: rotate(0deg);}
|
||||||
|
to {-o-transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
@keyframes rotation {
|
||||||
|
from {transform: rotate(0deg);}
|
||||||
|
to {transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
|
||||||
|
#output {
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 10px;
|
||||||
|
border-left: 0px;
|
||||||
|
border-right: 0px;
|
||||||
|
padding-left: 0px;
|
||||||
|
padding-right: 0px;
|
||||||
|
display: none;
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
font-family: 'Lucida Console', Monaco, monospace;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source_code {
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<link rel="stylesheet" type="text/css" href="highlight.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="emscripten_border">
|
||||||
|
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
|
||||||
|
</div>
|
||||||
|
<textarea id="output" rows="8"></textarea>
|
||||||
|
|
||||||
|
<div class="source_code">@htmlified_source_code@</div>
|
||||||
|
|
||||||
|
<script type='text/javascript'>
|
||||||
|
var Module = {
|
||||||
|
preRun: [],
|
||||||
|
postRun: [],
|
||||||
|
print: (function() {
|
||||||
|
var element = document.getElementById('output');
|
||||||
|
if (element) element.value = ''; // clear browser cache
|
||||||
|
return function(text) {
|
||||||
|
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||||
|
// These replacements are necessary if you render to raw HTML
|
||||||
|
//text = text.replace(/&/g, "&");
|
||||||
|
//text = text.replace(/</g, "<");
|
||||||
|
//text = text.replace(/>/g, ">");
|
||||||
|
//text = text.replace('\n', '<br>', 'g');
|
||||||
|
console.log(text);
|
||||||
|
if (element) {
|
||||||
|
element.value += text + "\n";
|
||||||
|
element.scrollTop = element.scrollHeight; // focus on bottom
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})(),
|
||||||
|
canvas: (() => {
|
||||||
|
var canvas = document.getElementById('canvas');
|
||||||
|
|
||||||
|
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
||||||
|
// application robust, you may want to override this behavior before shipping!
|
||||||
|
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
|
||||||
|
canvas.addEventListener("webglcontextlost", (e) => { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
})(),
|
||||||
|
setStatus: (text) => {},
|
||||||
|
totalDependencies: 0,
|
||||||
|
monitorRunDependencies: (left) => {
|
||||||
|
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||||
|
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Module.setStatus('Downloading...');
|
||||||
|
window.onerror = (event) => {
|
||||||
|
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus
|
||||||
|
Module.setStatus('Exception thrown, see JavaScript console');
|
||||||
|
Module.setStatus = (text) => {
|
||||||
|
if (text) console.error('[post-exception status] ' + text);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script async type="text/javascript" src="index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user