Skip to content

Instantly share code, notes, and snippets.

@tuttlem
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuttlem/09361eaff790c2289023 to your computer and use it in GitHub Desktop.
Save tuttlem/09361eaff790c2289023 to your computer and use it in GitHub Desktop.
Particle system
#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