Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions allegro.js
Original file line number Diff line number Diff line change
Expand Up @@ -1867,15 +1867,18 @@ function log(string)
{
if (ALLEGRO_CONSOLE && console) console.log(string);
if (!_debug_enabled) return;
_debug_element.innerHTML = _debug_element.innerHTML + string + "<br/>";
if (_debug_element.nodeName.toLowerCase() == "textarea") _debug_element.value = _debug_element.value + string + "\n";
else _debug_element.innerHTML = _debug_element.innerHTML + string + "<br/>";
_debug_element.scrollTop = _debug_element.scrollHeight;
}

/// Wipes the debug console
/// Clears the debug element of any text. Useful if you want to track changing values in real time without clogging the browser. Just call it at the beginning every loop()!
function wipe_log()
{
if (!_debug_enabled) return;
_debug_element.innerHTML = "";
if (_debug_element.nodeName.toLowerCase() == "textarea") _debug_element.value = "";
else _debug_element.innerHTML = "";
}

//@}
35 changes: 35 additions & 0 deletions emscripten/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## A lousy C port of a lousy JS port of a C library

*Allegro have been to JS and back*

**You think you're a hardcore allegro programmer? PROVE IT!**

### How do I make a C game for allegro.js?

1. Clone this repository
2. Install emscripten
3. Read `allegro.h`
4. Read and understand the examples
5. Write code
6. Compile-it
7. Enjoy

You don't need to write a single line of Javascript or HTML ! !

### How different is it from allegro.js

There is several tiny differences:
* All globals are functions (because emscripten)
* Because of name clash, rand and log have been renamed to rand16 and logmsg
* When passing an array parameter, you'll also have to pass its length
* There is no such thing as default parameters, closures, etc. (this is C programming, for real)

### How to compile C code into an HTML+Javascript program?

Compile your code with `emcc`:
```bash
emcc --pre-js ../allegro.js --js-library ../allegro.js --js-library library.js -I. -o my_game.html my_game.c
```

Open the created html file with your favorite JS enabled internet browser.

201 changes: 201 additions & 0 deletions emscripten/allegro.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/**
I'm the C header, #include me!
**/

#ifndef _ALLEGRO_JS_H
#define _ALLEGRO_JS_H
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

/* CONFIGURATION ROUTINES */
extern void install_allegro(void);
extern void allegro_init(void);
extern void allegro_init_all(const char *canvas_id, int w, int h, int menu, const int *enable_keys, int enable_keys_len);
#define END_OF_MAIN()

/* MOUSE ROUTINES */
extern int mouse_b(void);
extern int mouse_pressed(void);
extern int mouse_released(void);
extern int mouse_x(void);
extern int mouse_y(void);
extern int mouse_z(void);
extern int mouse_mx(void);
extern int mouse_my(void);
extern int mouse_mz(void);

extern int install_mouse(int menu);
extern int remove_mouse(void);
extern int show_mouse(void);
extern int hide_mouse(void);

/* TOUCH ROUTINES */
typedef struct {
int x, y, mx, my, px, py, sx, sy, id, age, dead;
} TOUCH_OBJECT;
extern TOUCH_OBJECT* touch(int *len);
extern TOUCH_OBJECT* touch_pressed(int *len);
extern TOUCH_OBJECT* touch_released(int *len);
extern void install_touch(void);
extern void remove_touch(void);

/* TIMER ROUTINES */
#define SECS_TO_TIMER(secs) ( secs*1000 )
#define MSEC_TO_TIMER(msec) ( msec )
#define BPS_TO_TIMER(bps) ( 1000./(float)bps )
#define BPM_TO_TIMER(bpm) ( 60*1000./(float)bpm )
typedef void (*procedure)(void);
typedef void (*bar)(float progress);
extern void install_timer(void);
extern long altime(void);
extern void install_int(procedure p, long msec);
extern void install_int_ex(procedure p, long speed);
extern void loop(procedure p, long speed);
extern void loading_bar(float progress);
extern void ready(procedure p, bar b);
extern void remove_int(procedure p);
extern void remove_all_ints(void);

/* KEYBOARD ROUTINES */
const char KEY_A = 0x41, KEY_B = 0x42, KEY_C = 0x43, KEY_D = 0x44, KEY_E = 0x45, KEY_F = 0x46, KEY_G = 0x47,
KEY_H = 0x48, KEY_I = 0x49, KEY_J = 0x4A, KEY_K = 0x4B, KEY_L = 0x4C, KEY_M = 0x4D, KEY_N = 0x4E,
KEY_O = 0x4F, KEY_P = 0x50, KEY_Q = 0x51, KEY_R = 0x52, KEY_S = 0x53, KEY_T = 0x54, KEY_U = 0x55,
KEY_V = 0x56, KEY_W = 0x57, KEY_X = 0x58, KEY_Y = 0x59, KEY_Z = 0x5A,
KEY_0 = 0x30, KEY_1 = 0x31, KEY_2 = 0x32, KEY_3 = 0x33, KEY_4 = 0x34, KEY_5 = 0x35, KEY_6 = 0x36,
KEY_7 = 0x37, KEY_8 = 0x38, KEY_9 = 0x39,
KEY_0_PAD = 0x60, KEY_1_PAD = 0x61, KEY_2_PAD = 0x62, KEY_3_PAD = 0x63, KEY_4_PAD = 0x64, KEY_5_PAD = 0x65,
KEY_6_PAD = 0x66, KEY_7_PAD = 0x67, KEY_8_PAD = 0x68, KEY_9_PAD = 0x69,
KEY_F1 = 0x70, KEY_F2 = 0x71, KEY_F3 = 0x72, KEY_F4 = 0x73, KEY_F5 = 0x74, KEY_F6 = 0x75, KEY_F7 = 0x76,
KEY_F8 = 0x77, KEY_F9 = 0x78, KEY_F10 = 0x79, KEY_F11 = 0x7a, KEY_F12 = 0x7b,
KEY_ESC = 0x1B, KEY_TILDE = 0xc0, KEY_MINUS = 0xbd, KEY_EQUALS = 0xbb, KEY_BACKSPACE = 0x08, KEY_TAB = 0x09,
KEY_OPENBRACE = 0xdb, KEY_CLOSEBRACE = 0xdd, KEY_ENTER = 0x0D, KEY_COLON = 0xba, KEY_QUOTE = 0xde,
KEY_BACKSLASH = 0xdc, KEY_COMMA = 0xbc, KEY_STOP = 0xbe, KEY_SLASH = 0xBF, KEY_SPACE = 0x20,
KEY_INSERT = 0x2D, KEY_DEL = 0x2E, KEY_HOME = 0x24, KEY_END = 0x23, KEY_PGUP = 0x21, KEY_PGDN = 0x22,
KEY_LEFT = 0x25, KEY_RIGHT = 0x27, KEY_UP = 0x26, KEY_DOWN = 0x28, KEY_SLASH_PAD = 0x6F, KEY_ASTERISK = 0x6A,
KEY_MINUS_PAD = 0x6D, KEY_PLUS_PAD = 0x6B, KEY_ENTER_PAD = 0x0D, KEY_PRTSCR = 0x2C, KEY_PAUSE = 0x13,
KEY_EQUALS_PAD = 0x0C, KEY_LSHIFT = 0x10, KEY_RSHIFT = 0x10, KEY_LCONTROL = 0x11, KEY_RCONTROL = 0x11,
KEY_ALT = 0x12, KEY_ALTGR = 0x12, KEY_LWIN = 0x5b, KEY_RWIN = 0x5c, KEY_MENU = 0x5d, KEY_SCRLOCK = 0x9d,
KEY_NUMLOCK = 0x90, KEY_CAPSLOCK = 0x14;
extern int* key(void);
extern int* pressed(void);
extern int* released(void);
extern int install_keyboard(const int *enable_keys, int enable_keys_len);
extern int remove_keyboard(void);

/* BITMAP ROUTINES */
typedef struct {
int handle;
int w, h;
} BITMAP_OBJECT;
extern BITMAP_OBJECT* create_bitmap(int width, int height);
extern BITMAP_OBJECT* load_bitmap(const char *filename);
extern BITMAP_OBJECT* load_bmp(const char *filename);
extern BITMAP_OBJECT** load_sheet(const char *filename, int w, int h, int *len);

/* GRAPHICS MODES */
extern BITMAP_OBJECT* canvas(void);
extern int SCREEN_W(void);
extern int SCREEN_H(void);
extern int set_gfx_mode(const char *canvas_id, int width, int height, int smooth);

/* DRAWING PRIMITIVES */
#define PI = 3.14159265
#define PI2 = 6.2831853
#define PI_2 = 1.570796325
#define PI_3 = 1.04719755
#define PI_4 = 0.7853981625
#define RAD(d) ( -d*PI/180.0 )
#define DEG(r) ( -r*180.0/PI )
extern int makecol(char r, char g, char b, char a);
extern int makecolf(float r, float g, float b, float a);
extern char getr(int colour);
extern char getg(int colour);
extern char getb(int colour);
extern char geta(int colour);
extern float getrf(int colour);
extern float getgf(int colour);
extern float getbf(int colour);
extern float getaf(int colour);
extern int getpixel(BITMAP_OBJECT *bitmap, int x, int y);
extern void putpixel(BITMAP_OBJECT *bitmap, int x, int y, int colour);
extern void clear_bitmap(BITMAP_OBJECT *bitmap);
extern void clear_to_color(BITMAP_OBJECT *bitmap, int colour);
extern void line(BITMAP_OBJECT *bitmap, int x1, int y1, int x2, int y2, int colour, int width);
extern void vline(BITMAP_OBJECT *bitmap, int x, int y1, int y2, int colour, int width);
extern void hline(BITMAP_OBJECT *bitmap, int x1, int y, int x2, int colour, int width);
extern void triangle(BITMAP_OBJECT *bitmap, int x1, int y1, int x2, int y2, int x3, int y3, int colour, int width);
extern void trianglefill(BITMAP_OBJECT *bitmap, int x1, int y1, int x2, int y2, int x3, int y3, int colour);
extern void polygon(BITMAP_OBJECT *bitmap, int vertices, const int *points, int colour, int width);
extern void polygonfill(BITMAP_OBJECT *bitmap, int vertices, const int *points, int colour);
extern void rect(BITMAP_OBJECT *bitmap, int x, int y, int w, int h, int colour, int width);
extern void rectfill(BITMAP_OBJECT *bitmap, int x, int y, int w, int h, int colour);
extern void circle(BITMAP_OBJECT *bitmap, int x, int y, int radius, int colour, int width);
extern void circlefill(BITMAP_OBJECT *bitmap, int x, int y, int radius, int colour);
extern void arc(BITMAP_OBJECT *bitmap, int x, int y, float ang1, float ang2, int radius, int colour, int width);
extern void arcfill(BITMAP_OBJECT *bitmap, int x, int y, float ang1, float ang2, int radius, int colour);

/* BLITTING AND SPRITES */
extern void draw_sprite(BITMAP_OBJECT *bmp, BITMAP_OBJECT *sprite, int x, int y);
extern void scaled_sprite(BITMAP_OBJECT *bmp, BITMAP_OBJECT *sprite, int x, int y, float sx, float sy);
extern void rotate_sprite(BITMAP_OBJECT *bmp, BITMAP_OBJECT *sprite, int x, int y, float angle);
extern void pivot_sprite(BITMAP_OBJECT *bmp, BITMAP_OBJECT *sprite, int x, int y, int cx, int cy, float angle);
extern void rotate_scaled_sprite(BITMAP_OBJECT *bmp, BITMAP_OBJECT *sprite, int x, int y, float angle, float sx, float sy);
extern void pivot_scaled_sprite(BITMAP_OBJECT *bmp, BITMAP_OBJECT *sprite, int x, int y, int cx, int cy, float angle, float sx, float sy);
extern void blit(BITMAP_OBJECT *source, BITMAP_OBJECT *dest, int sx, int sy, int dx, int dy, int w, int h);
extern void simple_blit(BITMAP_OBJECT *source, BITMAP_OBJECT *dest, int x, int y);
extern void stretch_blit(BITMAP_OBJECT *source, BITMAP_OBJECT *dest, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh);

/* TEXT OUTPUT */
typedef int FONT_OBJECT;
extern FONT_OBJECT* font(void);
extern FONT_OBJECT* load_base64_font(char *data);
extern FONT_OBJECT* load_font(char *filename);
extern FONT_OBJECT* create_font(char *family);
extern void textout(BITMAP_OBJECT *bitmap, FONT_OBJECT *font, const char *string, int x, int y, int size, int colour, int outline, int width);
extern void textout_centre(BITMAP_OBJECT *bitmap, FONT_OBJECT *font, const char *string, int x, int y, int size, int colour, int outline, int width);
extern void textout_right(BITMAP_OBJECT *bitmap, FONT_OBJECT *font, const char *string, int x, int y, int size, int colour, int outline, int width);

/* SOUND ROUTINES */
typedef int SAMPLE_OBJECT;
extern void install_sound(void);
extern void set_volume(float volume);
extern float get_volume(void);
extern SAMPLE_OBJECT* load_sample(char *filename);
extern void destroy_sample(char *filename);
extern void play_sample(SAMPLE_OBJECT *sample, float vol, float freq, int loop);
extern void adjust_sample(SAMPLE_OBJECT *sample, float vol, float freq, int loop);
extern void stop_sample(SAMPLE_OBJECT *sample);
extern void pause_sample(SAMPLE_OBJECT *sample);

/* HELPER MATH FUNCTIONS */
extern unsigned short rand16(void);
extern int rand32(void);
extern float frand(void);
#define abs(a) ( (a<0)?(-a):(a) )
extern float length(float x, float y);
extern float distance(float x1, float y1, float x2, float y2);
extern float distance2(float x1, float y1, float x2, float y2);
extern float linedist(float ex1, float ey1, float ex2, float ey2, float x, float y);
extern float lerp(float from, float to, float progress);
extern float dot(float x1, float y1, float x2, float y2);
extern int sgn(float a);
extern float angle(float x1, float y1, float x2, float y2);
extern float anglediff(float a, float b);
extern float clamp(float value, float min, float max);
extern float scale(float value, float min, float max, float min2, float max2);
extern float scaleclamp(float value, float min, float max, float min2, float max2);

/* DEBUG FUNCTIONS */
extern int ALLEGRO_CONSOLE;
extern void enable_debug(const char *id);
extern void logmsg(const char *string);
extern void wipe_log(void);

#ifdef __cplusplus
}
#endif

#endif /* _ALLEGRO_JS_H */
26 changes: 26 additions & 0 deletions emscripten/examples/exbmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <stdlib.h>
#include <allegro.h>

// Globally declared bitmap object
BITMAP_OBJECT *logo;

void when_ready(void) {
// Renders the loaded image on the screen
stretch_blit(logo, canvas(), 0, 0, logo->w, logo->h, 0, 0, SCREEN_W(), SCREEN_H());
}

int main(void) {
// Initialises allegro.js
allegro_init();

// Installs graphics at given canvas in 640x480 resolution
set_gfx_mode("canvas", 640, 480, 1);

// Loads an image into the bitmap object
logo = load_bmp("data/allegro.png");

ready(when_ready, NULL);

return 0;
}
END_OF_MAIN()
94 changes: 94 additions & 0 deletions emscripten/examples/exbounce.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include <stdlib.h>
#include <allegro.h>

// bitmap objects
BITMAP_OBJECT *clouds, *ball;

// sample object
SAMPLE_OBJECT *bounce;

// size and speed of the ball
const int size=64, speed=5;

// positon of the ball
float cx=100, cy=100;

// velocity of the ball
float vx=speed, vy=speed;

// drawing function
void draw(void)
{
// draw allegro clouds background
stretch_blit(clouds, canvas(), 0, 0, clouds->w, clouds->h, 0, 0, SCREEN_W(), SCREEN_H());

// draws the ball centered
draw_sprite(canvas(), ball, cx, cy);
}

// update game logic
void update(void) {
// did the ball bounce off the wall this turn?
int bounced = 0;

// if the ball is going to collide with screen bounds
// after applying velocity, if so, reverse velocity
// and remember that it bonced
if (cx+vx > SCREEN_W()) { vx = -speed; bounced=1; }
if (cy+vy > SCREEN_H()) { vy = -speed*3; bounced=1; }
if (cx+vx < 0) { vx = speed; bounced=1; }
if (cy+vy < 0) { vy = speed; bounced=1; }

// move the ball
cx += vx;
cy += vy;

// if it bounced, play a sound
if (bounced) play_sample(bounce, 1., 1., 0);

// add gravity
vy += .3;
}

void in_loop(void) {
// clear screen
clear_to_color(canvas(), makecol(255, 255, 255, 255));

// update game logic
update();

// render everything
draw();
}

void when_ready(void) {
loop(in_loop, BPS_TO_TIMER(60));
}

// entry point of our example
int main(void) {
// enable debugging to console element
enable_debug("output");

// put allegro in canvas with id="canvas"
// make the dimesnions 640x480
set_gfx_mode("canvas", 640, 480, 1);

install_sound();

// load ball image
ball = load_bmp("data/planet.png");

// load background image
clouds = load_bmp("data/clouds.png");

// load the bounce sound
bounce = load_sample("data/bounce.mp3");

// make sure everything has loaded
ready(when_ready, NULL);

// the end
return 0;
}
END_OF_MAIN()
Loading