Last active
August 29, 2015 14:13
-
-
Save tuttlem/09361eaff790c2289023 to your computer and use it in GitHub Desktop.
Particle system
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <alloc.h> | |
#include <conio.h> | |
#include <stdlib.h> | |
#define VIDEO_MODE_MCGA 0x13 | |
#define VIDEO_MODE_TEXT 0x03 | |
#define PARTICLE_COUNT 1000 | |
#define GRAVITY 0.1f | |
#define set_pixel(x, y, c, v) (v[x+(y<<6)+(y<<8)] = c) | |
#define get_pixel(x, y, c, v) (v[x+(y<<6)+(y<<8)]) | |
unsigned char far *vga = (unsigned char far *)0x0A0000000; | |
typedef struct _particle { | |
float x, y; | |
float vx, vy; | |
float life, decay; | |
} particle; | |
particle *particles; | |
void set_video_mode(unsigned char); | |
void set_palette(int, int, int, int); | |
void init_particles(); | |
void kill_particles(); | |
void init_particle(int); | |
void draw_particle(int); | |
void update_particle(int); | |
void bloom(); | |
void main() { | |
init_particles(); | |
for (int i = 0; i < PARTICLE_COUNT; i ++) { | |
init_particle(i); | |
} | |
while (!kbhit()) { | |
for (int i = 0; i < PARTICLE_COUNT; i ++) { | |
update_particle(i); | |
draw_particle(i); | |
} | |
bloom(); | |
} | |
kill_particles(); | |
} | |
void init_particles() { | |
set_video_mode(VIDEO_MODE_MCGA); | |
particles = (particle*) malloc(sizeof(particle) * PARTICLE_COUNT); | |
for (int i = 0; i < PARTICLE_COUNT; i ++) { | |
init_particle(i); | |
} | |
for (int c = 0; c < 64; c ++) { | |
unsigned char i = (unsigned char)c; | |
set_palette(i , i , 0 , 0); | |
set_palette(64 + i , 63, i >> 1 , 0); | |
set_palette(128 + i, 63, 32 + (i >> 1), 0); | |
set_palette(191 + i, 63, 63 , i); | |
} | |
} | |
void kill_particles() { | |
free(particles); | |
set_video_mode(VIDEO_MODE_TEXT); | |
} | |
void set_video_mode(unsigned char mode) { | |
asm { | |
mov ah, 0x00 | |
mov al, mode | |
int 0x10 | |
} | |
} | |
void set_palette(int c, int r, int g, int b) { | |
asm { | |
mov dx, 0x03c7 | |
mov ax, c | |
out dx, al | |
add dx, 2 | |
mov ax, r | |
out dx, al | |
mov ax, g | |
out dx, al | |
mov ax, b | |
out dx, al | |
} | |
} | |
void init_particle(int idx) { | |
particle *p = &particles[idx]; | |
p->x = 160.0f; p->y = 100.0f; | |
p->vx = (-200 + random(400)) / 70.0f; | |
p->vy = (-200 + random(400)) / 50.0f; | |
p->life = 255.0f; | |
p->decay = 0.95f + (random(5) / 100.0f); | |
} | |
void draw_particle(int idx) { | |
particle *p = &particles[idx]; | |
if (p->x >= 0.0f && p->x < 320.0f && | |
p->y >= 0.0f && p->y < 200.0f && | |
p->life > 0.0f) { | |
unsigned char col = (unsigned char)p->life; | |
set_pixel((int)p->x, (int)p->y, col, vga); | |
} | |
} | |
void update_particle(int idx) { | |
particle *p = &particles[idx]; | |
p->x += p->vx; | |
p->y += p->vy; | |
p->vy += GRAVITY; | |
p->vx *= 0.999f; | |
p->life *= p->decay; | |
if (p->x < 0.0f || p->x > 319.0f || | |
p->y < 0.0f || p->y > 199.0f || | |
p->life < 0.0f) { | |
init_particle(idx); | |
} | |
} | |
void bloom() { | |
asm { | |
mov ax, 0x0a000 | |
mov es, ax | |
mov di, 320 | |
mov cx, 63680 | |
} | |
next_pixel: | |
asm { | |
xor ax, ax | |
mov al, [es:di] | |
add al, [es:di-1] | |
adc ah, 0 | |
add al, [es:di+1] | |
adc ah, 0 | |
add al, [es:di-320] | |
adc ah, 0 | |
shr ax, 2 | |
mov [es:di], al | |
inc di | |
dec cx | |
jnz next_pixel | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment