Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added new blend modes include multiply, add, subtract, dissolve, etc.… #45

Merged
merged 3 commits into from
Oct 24, 2021
Merged
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
3 changes: 2 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ add_subdirectory(audio)
add_subdirectory(sprites)
add_subdirectory(colour)
#add_subdirectory(sfx)
add_subdirectory(music)
add_subdirectory(music)
add_subdirectory(blend_modes)
7 changes: 7 additions & 0 deletions examples/blend_modes/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
picosystem_executable(
blend_modes
blend_modes.cpp
)

pixel_double(blend_modes)
disable_startup_logo(blend_modes)
1,896 changes: 1,896 additions & 0 deletions examples/blend_modes/blend_modes.cpp

Large diffs are not rendered by default.

42 changes: 27 additions & 15 deletions examples/sprites/sprites.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ float deg_to_rad(float d) {
// draw the world
void draw(uint32_t tick) {
// clear the background
pen(2, 3, 4);
alpha();
pen(1, 1, 1);
clear();

pen(10, 10, 10);
text("Choose your weapon:", 10, 10);
text("Choose your weapon:", 8, 10);

// animate towards the selected weapons angle
static float angle = 0.0f;
Expand Down Expand Up @@ -97,34 +98,45 @@ void draw(uint32_t tick) {
// size to draw weapon (closer = larger)
int32_t scale = ((cos(deg_to_rad(item_angle)) + 1.0f) * 8.0f) + 8.0f;

int32_t a = scale / 1.5;
a = a > 15 ? 15 : a;

// draw the shadow
alpha(a / 8);
pen(1, 1, 1);
int32_t sw = scale + (bounce / 3);
int32_t sh = sw / 3;
fellipse(60 + x, 55 + y + (scale / 1.2), sw / 2, sh / 2);
blend(PEN);
int32_t sw = scale + (bounce / 2);
int32_t sh = sw / 4;
pen(0, 0, 0);
sprite(
weapons[i].id, // sprite id
60 + x - (sw / 2), 50 + y + (scale / 1.2), // position
1, 1,
sw, sh // size
);

blend(ALPHA);

// draw the weapon sprite
int32_t a = ((cos(deg_to_rad(item_angle)) + 1.0f) * 6.0f) + 4.0f;
a = a > 15 ? 15 : a;
alpha(a);
sprite(
weapons[i].id, // sprite id
60 + x - (scale / 2), 55 + y - (scale / 2) + bounce, // position
1, 1,
scale, scale // size
);
alpha(15);

//pen(15, 15, 15);
//text(str(a), 60 + x - (scale / 2), 55 + y - (scale / 2) + bounce);
}

alpha(15);


// centre name of weapon at bottom of screen
int label_width = 40;//text_width(weapons[selected].name);
pen(8, 11, 11);
frect(60 - label_width / 2 - 3, 104 - 3, label_width + 6, 13);
int32_t lw, lh;
measure(weapons[selected].name, lw, lh);
pen(12, 12, 12);
frect(60 - lw / 2 - 3, 104 - 3, lw + 6, 13);
pen(0, 0, 0);
text(weapons[selected].name, 60 - (label_width / 2), 104);
text(weapons[selected].name, 60 - (lw / 2), 104);
}


6 changes: 3 additions & 3 deletions libraries/assets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ namespace picosystem {
{5, 0xf8, 0x18, 0x30, 0x30, 0x60, 0x60, 0x60, 0x00},
{5, 0x70, 0xd8, 0xd8, 0x70, 0xd8, 0xd8, 0x70, 0x00},
{5, 0x70, 0xd8, 0xd8, 0x78, 0x18, 0x98, 0x70, 0x00},
{2, 0x00, 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0x00, 0x00},
{2, 0x00, 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0xc0, 0x00},
{2, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0x00},
{2, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0xc0},
{4, 0x00, 0x00, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x00},
{5, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00},
{4, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x60, 0xc0, 0x00},
Expand Down Expand Up @@ -130,7 +130,7 @@ namespace picosystem {
{3, 0xc0, 0xc0, 0xe0, 0xc0, 0xc0, 0xc0, 0x60, 0x00},
{5, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xd8, 0x68, 0x00},
{5, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0x70, 0x20, 0x00},
{6, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xec, 0x5c, 0x00},
{7, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0x6c, 0x00},
{6, 0x00, 0x00, 0xcc, 0x78, 0x30, 0x78, 0xcc, 0x00},
{5, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0x78, 0x18, 0x70},
{5, 0x00, 0x00, 0xf8, 0x30, 0x60, 0xc0, 0xf8, 0x00},
Expand Down
143 changes: 143 additions & 0 deletions libraries/blend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,150 @@ namespace picosystem {
// step destination and source
pd++; so += ss;
}
}

// compares source and destination RGB channels and picks the darker of the
// two. if there is global alpha the result is then blended with the
// destination.
void DARKEN(color_t *ps, uint32_t so, int32_t ss, color_t *pd, uint32_t c) {
while(c--) {
color_t s = *(ps + (so >> 16));
color_t d = *pd;

uint16_t sr = (s & 0x000f), sg = (s & 0xf000), sb = (s & 0x0f00);
uint16_t dr = (d & 0x000f), dg = (d & 0xf000), db = (d & 0x0f00);
uint16_t sa = (s & 0x00f0);

s = (sr < dr ? sr : dr) | (sg < dg ? sg : dg) | (sb < db ? sb : db) | sa;
ALPHA(&s, 0, 0, pd, 1);

// step destination and source
pd++; so += ss;
}
}

// compares source and destination RGB channels and picks the lighter of the
// two. if there is global alpha the result is then blended with the
// destination.
void LIGHTEN(color_t *ps, uint32_t so, int32_t ss, color_t *pd, uint32_t c) {
while(c--) {
color_t s = *(ps + (so >> 16));
color_t d = *pd;

uint16_t sr = (s & 0x000f), sg = (s & 0xf000), sb = (s & 0x0f00);
uint16_t dr = (d & 0x000f), dg = (d & 0xf000), db = (d & 0x0f00);
uint16_t sa = (s & 0x00f0);

s = (sr > dr ? sr : dr) | (sg > dg ? sg : dg) | (sb > db ? sb : db) | sa;
ALPHA(&s, 0, 0, pd, 1);

// step destination and source
pd++; so += ss;
}
}

// compares source and destination RGB channels and picks the lighter of the
// two. if there is global alpha the result is then blended with the
// destination.
void ADD(color_t *ps, uint32_t so, int32_t ss, color_t *pd, uint32_t c) {
while(c--) {
color_t s = *(ps + (so >> 16));
color_t d = *pd;

int32_t sr = (s & 0x000f), sg = (s & 0xf000), sb = (s & 0x0f00);
int32_t dr = (d & 0x000f), dg = (d & 0xf000), db = (d & 0x0f00);
int32_t sa = (s & 0x00f0);

dr += sr;
dg += sg;
db += sb;

dr = dr > 15 ? 15 : dr;
dg = dg > (15 << 12) ? (15 << 12) : dg;
db = db > (15 << 8) ? (15 << 8) : db;

s = dr | dg | db | sa;

ALPHA(&s, 0, 0, pd, 1);

// step destination and source
pd++; so += ss;
}
}

// compares source and destination RGB channels and picks the lighter of the
// two. if there is global alpha the result is then blended with the
// destination.
void SUBTRACT(color_t *ps, uint32_t so, int32_t ss, color_t *pd, uint32_t c) {
while(c--) {
color_t s = *(ps + (so >> 16));
color_t d = *pd;

int32_t sr = (s & 0x000f), sg = (s & 0xf000), sb = (s & 0x0f00);
int32_t dr = (d & 0x000f), dg = (d & 0xf000), db = (d & 0x0f00);
int32_t sa = (s & 0x00f0);

dr = dr > sr ? dr - sr : 0;
dg = dg > sg ? dg - sg : 0;
db = db > sb ? db - sb : 0;

s = dr | dg | db | sa;
ALPHA(&s, 0, 0, pd, 1);

// step destination and source
pd++; so += ss;
}
}

// compares source and destination RGB channels and picks the lighter of the
// two. if there is global alpha the result is then blended with the
// destination.
void MULTIPLY(color_t *ps, uint32_t so, int32_t ss, color_t *pd, uint32_t c) {
while(c--) {
color_t s = *(ps + (so >> 16));
color_t d = *pd;

int32_t sr = (s & 0x000f), sg = (s & 0xf000), sb = (s & 0x0f00);
int32_t dr = (d & 0x000f), dg = (d & 0xf000), db = (d & 0x0f00);
int32_t sa = (s & 0x00f0);

dr = (sr * dr) >> 4;
dg = (sg * dg) >> 18;
db = (sb * db) >> 12;

s = dr | dg | db | sa;
ALPHA(&s, 0, 0, pd, 1);

// step destination and source
pd++; so += ss;
}
}

uint32_t _hash(uint32_t v) {
int n = 4;
do {
v = ((v >> 8) ^ v) * 0xD2 + n;
} while(--n);
return v;
}
// performs a "fizzlefade" style effect by only copying the source pixel if
// the destination pointer address hashes to a value < source alpha
void DISSOLVE(color_t *ps, uint32_t so, int32_t ss, color_t *pd, uint32_t c) {
while(c--) {
color_t s = *(ps + (so >> 16));

int32_t sa = (s & 0x00f0) >> 4;

// create 4-bit hash of destination pointer...
int32_t h = _hash(int32_t(pd) >> 1) & 0x000f;
h = h == 0 ? 0 : h - 1;
if(h < sa) {
COPY(&s, 0, 0, pd, 1);
}

// step destination and source
pd++; so += ss;
}
}

// blends the source and destination
Expand Down
4 changes: 2 additions & 2 deletions libraries/hardware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ namespace picosystem {
FRMCTR1 = 0xB1, FRMCTR2 = 0xB2, GMCTRP1 = 0xE0, GMCTRN1 = 0xE1,
INVOFF = 0x20, SLPOUT = 0x11, DISPON = 0x29, GAMSET = 0x26,
DISPOFF = 0x28, RAMWR = 0x2C, INVON = 0x21, CASET = 0x2A,
RASET = 0x2B, STE = 0x44
RASET = 0x2B, STE = 0x44, DGMEN = 0xBA,
};

_screen_command(SWRESET);
Expand All @@ -352,7 +352,7 @@ namespace picosystem {
_screen_command(TEON, 1, "\x00");
_screen_command(FRMCTR2, 5, "\x0C\x0C\x00\x33\x33");
_screen_command(COLMOD, 1, "\x03");
_screen_command(GAMSET, 1, "\x04");
_screen_command(GAMSET, 1, "\x01");

_screen_command(GCTRL, 1, "\x14");
_screen_command(VCOMS, 1, "\x25");
Expand Down
12 changes: 12 additions & 0 deletions libraries/picosystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,18 @@ namespace picosystem {
color_t* ps, uint32_t so, int32_t ss, color_t* pd, uint32_t c);
void PEN(
color_t* ps, uint32_t so, int32_t ss, color_t* pd, uint32_t c);
void DARKEN(
color_t* ps, uint32_t so, int32_t ss, color_t* pd, uint32_t c);
void LIGHTEN(
color_t* ps, uint32_t so, int32_t ss, color_t* pd, uint32_t c);
void ADD(
color_t* ps, uint32_t so, int32_t ss, color_t* pd, uint32_t c);
void SUBTRACT(
color_t* ps, uint32_t so, int32_t ss, color_t* pd, uint32_t c);
void MULTIPLY(
color_t* ps, uint32_t so, int32_t ss, color_t* pd, uint32_t c);
void DISSOLVE(
color_t* ps, uint32_t so, int32_t ss, color_t* pd, uint32_t c);

// audio
void play(
Expand Down