* WalrusIRC

You need to have 5 posts and not be part of restricted usergroups in order to use the WalrusIRC embedded shoutbox. However, you can also access our IRC channel called #CodeWalrus via EFnet.

Author Topic: Graphics and other system routines  (Read 9645 times)

0 Members and 1 Guest are viewing this topic.

Offline DarkestEx

  • Super User
  • Join Date: Jan 2015
  • Location: Germany
  • Posts: 1324
  • Post Rating Ratio: +10/-2
    • @0xbmuessig
    • @muessigb
    • My homepage
  • Gender: Male
Graphics and other system routines
« on: October 19, 2015, 10:31:05 pm »
Hello, in this topic you can suggest and vote for graphics and drawing routines that I we will use in he official API and system.

To start, I want to have some sprite routines, but I can't get them to work:
Code: [Select]
void oled_bdraws(int16_t x, int16_t y, uint8_t width, uint8_t height, const uint8_t bitmap[]) {
uint8_t ow = width;

if(width + x > BUFFER_WIDTH)
width -= width + x - BUFFER_WIDTH;
if(height + y > BUFFER_HEIGHT)
height -= height + y - BUFFER_HEIGHT;
if(width + x <= 0 || height + y <= 0)
return;

for(int yi = y; yi < (y + height); yi++) {
for(int xi = x; xi < (x + width); xi++) {
if((yi - y) < 0 || (xi - x) < 0)
continue;
if(bitmap[(yi - y) * ow + (xi - x)] > 0)
screen_buffer[yi * ow + xi] = bitmap[(yi - y) * ow + (xi - x)];
}
}
}

The language for all routines should be C, but many other languages can be ported pretty easily I guess.
There is one framebuffer called screen_buffer[128*128]. It is using a palette. If you want to make your own functions, just make them take inputs (coordiantes, colors, etc.) and let them write to screen_buffer. The color 0x00 is transparent when drawn.


  • Calculators owned: TI-84+, Casio 101-S, RPN-Calc, Hewlett-Packard 100LX, Hewlett-Packard 95LX
  • Consoles, mobile devices and vintage computers owned: Hewlett-Packard 100LX, Hewlett-Packard 95LX, Original Commodore 64C, Tektronix AWG2021, IBM X60s, IBM X60t, Nintendo DS Lite, Nintendo GameBoy Color, Nintendo GameCube, Xbox 360, Palm m5


Avatar drewn for me by Tabbes.

Offline c4ooo

  • Super User
  • CW Contest II Winner
  • *
  • Join Date: Aug 2015
  • Location: 127.0.0.1
  • Posts: 1007
  • Post Rating Ratio: +12/-4
  • Advanced forumer
  • Gender: Male
Re: Graphics and other system routines
« Reply #1 on: October 20, 2015, 12:33:07 am »
Here is an optimized circle drawing routine in java:
Code: [Select]
    public void drawCircle(int x, int y, int r) {
        double angle, x1, y1;
        for (angle = 0; angle < 90; angle += 0.1) {
            x1 = r * Math.cos(angle * Math.PI / 180);
            y1 = r * Math.sin(angle * Math.PI / 180);
            setPixel((int) (x + x1), (int) (y + y1)); //bottom left
            setPixel((int) (x + x1), (int) (y - y1)); //top left
            setPixel((int) (x - x1), (int) (y + y1)); //nottom right
            setPixel((int) (x - x1), (int) (y - y1)); // top right
        }
    }
I dont really know how you handle doubles/floats in c :P

setPixer is self explanatory:
Code: [Select]
    public void setPixel(int x, int y) {
        if (x >= 0 && x < width && y >= 0 && y < height) {
            pixels[x + width * y] = color;
        }
    }

Drawing filled circles is a bit more tricky:

Code: [Select]

    public void drawFillCircle(int x, int y, int r) {
        double angle, x1, y1;
        for (angle = 0; angle < 90; angle += 0.1) {
            x1 = r * Math.cos(angle * Math.PI / 180);
            y1 = r * Math.sin(angle * Math.PI / 180);
            setPixel((int) (x + x1), (int) (y + y1)); //bottom left
            setPixel((int) (x - x1), (int) (y + y1)); //nottom right
            for (double i = x - x1; i <= x + x1; i++) {
                setPixel((int) i, (int) (y + y1));
                setPixel((int) i, (int) (y - y1));
            }
        }
    }

Hope it helps you in some way ;)

Offline semiprocoder

  • Full User
  • Join Date: May 2015
  • Location:
  • Posts: 282
  • Post Rating Ratio: +2/-0
    • awesommee333
    • 114/11470
  • Gender: Male
Re: Graphics and other system routines
« Reply #2 on: October 20, 2015, 01:31:12 am »
Since graphics has extensive trig, have an index of already done trig values so that you don't have to always do the trig. For more accuracy you would obiously need to use full trig, but I think you could do angle vals 1-90 or something without wasting too much ram, like have a 360 b devoted to trig index, and a bit more to arc values
  • Calculators owned: ti nspire, ti 84 plus se
My cemetech username is awesommee333.

Offline c4ooo

  • Super User
  • CW Contest II Winner
  • *
  • Join Date: Aug 2015
  • Location: 127.0.0.1
  • Posts: 1007
  • Post Rating Ratio: +12/-4
  • Advanced forumer
  • Gender: Male
Re: Graphics and other system routines
« Reply #3 on: October 20, 2015, 01:43:05 am »
There will be no accuracy increase from using 1-360, just a speed decrease. Basicly all i need to do is calculate a quarter slice of the circle, then flip the values over the center to get the rest. ;)

Offline semiprocoder

  • Full User
  • Join Date: May 2015
  • Location:
  • Posts: 282
  • Post Rating Ratio: +2/-0
    • awesommee333
    • 114/11470
  • Gender: Male
Re: Graphics and other system routines
« Reply #4 on: October 20, 2015, 01:57:32 am »
Yeah thats why I was saying 1-90 instead of 1-360  :P

The 360 was 90*4(for num bytes in a float)=360
« Last Edit: October 20, 2015, 03:22:15 am by semiprocoder »
  • Calculators owned: ti nspire, ti 84 plus se
My cemetech username is awesommee333.

Offline DarkestEx

  • Super User
  • Join Date: Jan 2015
  • Location: Germany
  • Posts: 1324
  • Post Rating Ratio: +10/-2
    • @0xbmuessig
    • @muessigb
    • My homepage
  • Gender: Male
Re: Graphics and other system routines
« Reply #5 on: October 20, 2015, 09:14:52 am »
Oh that's awesome :)
I can't wait implement them all.
I am glad for any help with the graphics functions. As you all obviously know, the quality and speed of them massively affect all games that come out for the platform ;)

I really hope that more functions will follow. Especially from the calculator community who managed writing well working and fast, integer based graphics functions.
« Last Edit: October 20, 2015, 09:16:33 am by DarkestEx »
  • Calculators owned: TI-84+, Casio 101-S, RPN-Calc, Hewlett-Packard 100LX, Hewlett-Packard 95LX
  • Consoles, mobile devices and vintage computers owned: Hewlett-Packard 100LX, Hewlett-Packard 95LX, Original Commodore 64C, Tektronix AWG2021, IBM X60s, IBM X60t, Nintendo DS Lite, Nintendo GameBoy Color, Nintendo GameCube, Xbox 360, Palm m5


Avatar drewn for me by Tabbes.

Offline c4ooo

  • Super User
  • CW Contest II Winner
  • *
  • Join Date: Aug 2015
  • Location: 127.0.0.1
  • Posts: 1007
  • Post Rating Ratio: +12/-4
  • Advanced forumer
  • Gender: Male
Re: Graphics and other system routines
« Reply #6 on: October 20, 2015, 10:35:19 am »
Yeah thats why I was saying 1-90 instead of 1-360  :P

The 360 was 90*4(for num bytes in a float)=360
Whoops i completely revered the meaning of your post :P 
*facepalm*

Any how, although they definatly work, they might be optimizable. It has been a long time since i looked at that code.

Offline Streetwalrus

  • Professional slacker
  • Super User
  • Original 5
  • Join Date: Nov 2014
  • Location: Israel
  • Posts: 2903
  • Post Rating Ratio: +20/-0
  • ƎW∀⅁ ƎH⊥
  • Gender: Male
Re: Graphics and other system routines
« Reply #7 on: October 20, 2015, 10:54:26 am »
As DarkestEx said, integer routines will be favored as the hardware does not support floating point (which has to be emulated in software) so integer or fixed point math is going to be faster.
  • Calculators owned: TI-80, HP 40G, TI-84 Plus rev G (yay 128k RAM), TI-83 Plus Silver Edition (broken LCD), TI-82 Stats.fr (black), TI-Nspire CX rev C (yay Nlaunchy), TI-83+ SE ViewScreen



Offline semiprocoder

  • Full User
  • Join Date: May 2015
  • Location:
  • Posts: 282
  • Post Rating Ratio: +2/-0
    • awesommee333
    • 114/11470
  • Gender: Male
Re: Graphics and other system routines
« Reply #8 on: October 20, 2015, 11:53:05 am »
maybe then just have cos*100, estimated to an int, or something returned and ten you just manually divide later?


edit: maybe cos*128, so that to divide you just bit shift some places to the right(for any power of two, 128 may not be accurate enough, idk), which is faster.
« Last Edit: October 20, 2015, 12:08:43 pm by semiprocoder »
  • Calculators owned: ti nspire, ti 84 plus se
My cemetech username is awesommee333.

Offline Snektron

  • Lvl 69 Russian Snake
  • CodeWalrus Staff
  • Super User
  • Topic Management
  • Join Date: Dec 2014
  • Location: Netherlands
  • Posts: 3165
  • Post Rating Ratio: +32/-0
  • SSSssssss.....
    • RobinDeWalvis
    • Kzyrox
    • RobinDeWalvis
    • quantuminfinity
  • Gender: Male
Re: Graphics and other system routines
« Reply #9 on: October 20, 2015, 01:13:05 pm »
  • Calculators owned: TI-84+
Legends say if you spam more than DJ Omnimaga, you will become a walrus...


Offline semiprocoder

  • Full User
  • Join Date: May 2015
  • Location:
  • Posts: 282
  • Post Rating Ratio: +2/-0
    • awesommee333
    • 114/11470
  • Gender: Male
Re: Graphics and other system routines
« Reply #10 on: October 20, 2015, 04:28:47 pm »
Yay! Triangles are awesome! Unfortunately many simple graphics apis don't let you use them, like ti nspire lua. It would be amazing if the microcat api had triangles.

Also, I made a fast sin/cos/tan generating program. It doesnt give you the sin value, but forces you to input a value and have it multiplied by the sin, because otherwise it would be annoying to deal with. I have not tested my code yet and don't have time to right now, but here it is:
Code: [Select]
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
# define PI 3.14159265358979323846
void writeSines() {
FILE *myfile;
if ((myfile = fopen("C:\\Users\\Andrew\\vs\\sines\\sinesBYTE.txt", "w")) == NULL) {
printf("didnt open");
return;
}
unsigned char tempSin;
for (double i = 1.0; i <= 90.0; i += 1.0) {
tempSin = (unsigned char)(sin(i / 180.0*PI) * 256);
fprintf(myfile, "%d, ", tempSin);
double tempcheck = tempSin;
}
fclose(myfile);
}
//generated using writeSines(). doesnt include sin(90) because sin(90)*256=256>255, max for byte/unsigned char, so it wraps around to 0, which is pointless
unsigned char sinArray[90] = {0, 4, 8, 13, 17, 22, 26, 31, 35, 40, 44, 48, 53, 57, 61, 66, 70, 74, 79, 83, 87, 91, 95, 100, 104, 108, 112, 116, 120, 124, 127, 131, 135, 139, 143, 146, 150, 154, 157, 161, 164, 167, 171, 174, 177, 181, 184, 187, 190, 193, 196, 198, 201, 204, 207, 209, 212, 214, 217, 219, 221, 223, 226, 228, 230, 232, 233, 235, 237, 238, 240, 242, 243, 244, 246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 254, 255, 255, 255, 255, 255};
void fastSinMult(int *val, int degree) {
if (degree == 90) {
return;
}
else if (degree < 90 && degree>=0) {
*val = (*val)*sinArray[degree+1];
(*val) = (*val) >> 8;
return;
}
else if (degree > 90 && degree <= 180) {
fastSinMult(val, 180 - degree);
return;
}
else if (degree > 180 && degree <= 360) {
fastSinMult(val, degree - 180);
(*val) *= -1;
return;
}
else if (degree > 360)//not allowing negative degrees for now
fastSinMult(val, degree % 360);
}
void fastCosMult(int *val, int degree) {
fastSinMult(val, degree - 90);
}
void fastTanMult(int *val, int angle) {
int val1 = *val;
int val2 = *val;
fastSinMult(&val1, angle);
fastCosMult(&val2, angle);
(*val) = val1 / val2;
}
  • Calculators owned: ti nspire, ti 84 plus se
My cemetech username is awesommee333.

Offline DarkestEx

  • Super User
  • Join Date: Jan 2015
  • Location: Germany
  • Posts: 1324
  • Post Rating Ratio: +10/-2
    • @0xbmuessig
    • @muessigb
    • My homepage
  • Gender: Male
Re: Graphics and other system routines
« Reply #11 on: October 20, 2015, 04:35:12 pm »
Yay! Triangles are awesome! Unfortunately many simple graphics apis don't let you use them, like ti nspire lua. It would be amazing if the microcat api had triangles.

Also, I made a fast sin/cos/tan generating program. It doesnt give you the sin value, but forces you to input a value and have it multiplied by the sin, because otherwise it would be annoying to deal with. I have not tested my code yet and don't have time to right now, but here it is:
Code: [Select]
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
# define PI 3.14159265358979323846
void writeSines() {
FILE *myfile;
if ((myfile = fopen("C:\\Users\\Andrew\\vs\\sines\\sinesBYTE.txt", "w")) == NULL) {
printf("didnt open");
return;
}
unsigned char tempSin;
for (double i = 1.0; i <= 90.0; i += 1.0) {
tempSin = (unsigned char)(sin(i / 180.0*PI) * 256);
fprintf(myfile, "%d, ", tempSin);
double tempcheck = tempSin;
}
fclose(myfile);
}
//generated using writeSines(). doesnt include sin(90) because sin(90)*256=256>255, max for byte/unsigned char, so it wraps around to 0, which is pointless
unsigned char sinArray[90] = {0, 4, 8, 13, 17, 22, 26, 31, 35, 40, 44, 48, 53, 57, 61, 66, 70, 74, 79, 83, 87, 91, 95, 100, 104, 108, 112, 116, 120, 124, 127, 131, 135, 139, 143, 146, 150, 154, 157, 161, 164, 167, 171, 174, 177, 181, 184, 187, 190, 193, 196, 198, 201, 204, 207, 209, 212, 214, 217, 219, 221, 223, 226, 228, 230, 232, 233, 235, 237, 238, 240, 242, 243, 244, 246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 254, 255, 255, 255, 255, 255};
void fastSinMult(int *val, int degree) {
if (degree == 90) {
return;
}
else if (degree < 90 && degree>=0) {
*val = (*val)*sinArray[degree+1];
(*val) = (*val) >> 8;
return;
}
else if (degree > 90 && degree <= 180) {
fastSinMult(val, 180 - degree);
return;
}
else if (degree > 180 && degree <= 360) {
fastSinMult(val, degree - 180);
(*val) *= -1;
return;
}
else if (degree > 360)//not allowing negative degrees for now
fastSinMult(val, degree % 360);
}
void fastCosMult(int *val, int degree) {
fastSinMult(val, degree - 90);
}
void fastTanMult(int *val, int angle) {
int val1 = *val;
int val2 = *val;
fastSinMult(&val1, angle);
fastCosMult(&val2, angle);
(*val) = val1 / val2;
}
Thank you :)
As you were so kind and provided the functions, I will absolutely implement them :)
Especially the Sin tables are pretty useful.

I'll add you all to the special thanks list obviously for all your great code :)
« Last Edit: October 20, 2015, 05:00:42 pm by DarkestEx »
  • Calculators owned: TI-84+, Casio 101-S, RPN-Calc, Hewlett-Packard 100LX, Hewlett-Packard 95LX
  • Consoles, mobile devices and vintage computers owned: Hewlett-Packard 100LX, Hewlett-Packard 95LX, Original Commodore 64C, Tektronix AWG2021, IBM X60s, IBM X60t, Nintendo DS Lite, Nintendo GameBoy Color, Nintendo GameCube, Xbox 360, Palm m5


Avatar drewn for me by Tabbes.

Offline Snektron

  • Lvl 69 Russian Snake
  • CodeWalrus Staff
  • Super User
  • Topic Management
  • Join Date: Dec 2014
  • Location: Netherlands
  • Posts: 3165
  • Post Rating Ratio: +32/-0
  • SSSssssss.....
    • RobinDeWalvis
    • Kzyrox
    • RobinDeWalvis
    • quantuminfinity
  • Gender: Male
Re: Graphics and other system routines
« Reply #12 on: October 20, 2015, 04:57:13 pm »
Code: [Select]
public void circle(int cx, int cy, int r)
{
int f = 1-r;
int ddFx = 1;
int ddFy = -2*r;
int x = 0;
int y = r;

setPixel(cx, cy+r);
setPixel(cx, cy-r);
setPixel(cx+r, cy);
setPixel(cx-r, cy);

while (x < y)
{
if (f>=0)
{
y--;
ddFy += 2;
f += ddFy;
}

x++;
ddFx += 2;
f += ddFx;

setPixel(cx + x, cy + y);
setPixel(cx - x, cy + y);
setPixel(cx + x, cy - y);
setPixel(cx - x, cy - y);

setPixel(cx + y, cy + x);
setPixel(cx - y, cy + x);
setPixel(cx + y, cy - x);
setPixel(cx - y, cy - x);
}
}

Here's a sine/cosineless circle algoritm in java (midpoint circle/bresenham). Also you might want to thin about adding translations, since they;re really usefull.

EDIT: i've altered the circle algoritm for a filled circle
Code: [Select]
public void fcircle(int cx, int cy, int r)
{
int f = 1-r;
int ddFx = 1;
int ddFy = -2*r;
int x = 0;
int y = r;

for (int fr=r; fr>0; fr--)
{
setPixel(cx, cy+fr);
setPixel(cx, cy-fr);
setPixel(cx+fr, cy);
setPixel(cx-fr, cy);
}

setPixel(cx, cy);

while (x < y)
{
if (f >= 0)
{
y--;
ddFy += 2;
f += ddFy;
}

x++;
ddFx += 2;
f += ddFx;

for (int fx=x; fx>0; fx--)
{
setPixel(cx + fx, cy + y);
setPixel(cx - fx, cy + y);
setPixel(cx + fx, cy - y);
setPixel(cx - fx, cy - y);
}

for (int fy=y; fy>0; fy--)
{
setPixel(cx + fy, cy + x);
setPixel(cx - fy, cy + x);
setPixel(cx + fy, cy - x);
setPixel(cx - fy, cy - x);
}
}
}
« Last Edit: October 20, 2015, 05:05:52 pm by Cumred_Snektron »
  • Calculators owned: TI-84+
Legends say if you spam more than DJ Omnimaga, you will become a walrus...


Offline DarkestEx

  • Super User
  • Join Date: Jan 2015
  • Location: Germany
  • Posts: 1324
  • Post Rating Ratio: +10/-2
    • @0xbmuessig
    • @muessigb
    • My homepage
  • Gender: Male
Re: Graphics and other system routines
« Reply #13 on: October 20, 2015, 05:01:23 pm »
Code: [Select]
public void circle(int cx, int cy, int r)
{
int f = 1-r;
int ddFx = 1;
int ddFy = -2*r;
int x = 0;
int y = r;

setPixel(cx, cy+r);
setPixel(cx, cy-r);
setPixel(cx+r, cy);
setPixel(cx-r, cy);

while (x < y)
{
if (f>=0)
{
y--;
ddFy += 2;
f += ddFy;
}

x++;
ddFx += 2;
f += ddFx;

setPixel(cx + x, cy + y);
setPixel(cx - x, cy + y);
setPixel(cx + x, cy - y);
setPixel(cx - x, cy - y);

setPixel(cx + y, cy + x);
setPixel(cx - y, cy + x);
setPixel(cx + y, cy - x);
setPixel(cx - y, cy - x);
}
}

Here's a sine/cosineless circle algoritm (midpoint circle/bresenham). Also you might want to thin about adding translations, since they;re really usefull.
Thats great, thank you! :)

Rounded rectangles would be useful too I guess. And if somebody has a lightweight raycaster or raytracer written in C or who could port one, I would absolutely love to have it in the graphics library. At 120MHz core speed, a raytracer or raycaster is feasible and would allow for more great games.
  • Calculators owned: TI-84+, Casio 101-S, RPN-Calc, Hewlett-Packard 100LX, Hewlett-Packard 95LX
  • Consoles, mobile devices and vintage computers owned: Hewlett-Packard 100LX, Hewlett-Packard 95LX, Original Commodore 64C, Tektronix AWG2021, IBM X60s, IBM X60t, Nintendo DS Lite, Nintendo GameBoy Color, Nintendo GameCube, Xbox 360, Palm m5


Avatar drewn for me by Tabbes.

Offline semiprocoder

  • Full User
  • Join Date: May 2015
  • Location:
  • Posts: 282
  • Post Rating Ratio: +2/-0
    • awesommee333
    • 114/11470
  • Gender: Male
Re: Graphics and other system routines
« Reply #14 on: October 20, 2015, 07:57:25 pm »
Just wanted to point it out, I don't know any graphics so I won't be able to help you there.

Anyways, the trig functions, namely tan don't even give near the correct value, so here are the actual functions. I also updated sin to allow negative numbers, forgot to do that. Here is the new code, without any of the testing stuff that I had before that I was going to use:
Code: [Select]
unsigned char sinArray[90] = {0, 4, 8, 13, 17, 22, 26, 31, 35, 40, 44, 48, 53, 57, 61, 66, 70, 74, 79, 83, 87, 91, 95, 100, 104, 108, 112, 116, 120, 124, 127, 131, 135, 139, 143, 146, 150, 154, 157, 161, 164, 167, 171, 174, 177, 181, 184, 187, 190, 193, 196, 198, 201, 204, 207, 209, 212, 214, 217, 219, 221, 223, 226, 228, 230, 232, 233, 235, 237, 238, 240, 242, 243, 244, 246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 254, 255, 255, 255, 255, 255};
void fastSinMult(int *val, int degree) {
if (degree == 90) {
return;
}
else if (degree < 90 && degree>=0) {
*val = (*val)*sinArray[degree-1];
(*val) = (*val) >> 8;
return;
}
else if (degree > 90 && degree <= 180) {
fastSinMult(val, 180 - degree);
return;
}
else if (degree > 180 && degree <= 360) {
fastSinMult(val, degree - 180);
(*val) *= -1;
return;
}
else if (degree > 360)
fastSinMult(val, degree % 360);
else {
fastSinMult(val, -degree);
(*val) = -(*val);
}
}
void fastCosMult(int *val, int degree) {
fastSinMult(val, 90-degree);
}
void fastTanMult(int *val, int degree) {
int val1 = *val;
int val2 = *val;
fastSinMult(&val1, degree);
fastCosMult(&val2, degree);
(*val) = ((*val) * val1) / val2;
}

Also I want to do arccos, arctan, and arcsin, but I am not sure how I would do that with ints. If you have any ideas about that tell me.
Furthermore, should I make a simple vector library, like magnitude, dot product, cross product, etc. or do you already have that without floats, cause I think it would be quite easy to do.
« Last Edit: October 20, 2015, 08:16:06 pm by semiprocoder »
  • Calculators owned: ti nspire, ti 84 plus se
My cemetech username is awesommee333.

 


You can also use the following HTML or bulletin board code to share it on your page or forum signature!


Also do not forget to check our affiliates below.
Planet Casio BroniesQC TI-Planet BosaikNet