Author Topic: Prizm Useful Routines -- post here!  (Read 28080 times)

0 Members and 1 Guest are viewing this topic.

Ashbad

  • Guest
Prizm Useful Routines -- post here!
« on: May 23, 2011, 10:26:31 am »
Since Cemetech has one, I think we need one as well.  This section is where you can post any routines for the casio Prizm you make in C or SH4 assembly.  I don't think I have the liberty to post others' routines over here, but I'll be glad to start with some of my own, and I'm sure Qwerty will soon post some of his very well done SH4 routines [nice and optimized, too!] such as his LRNG.  Here are a few in C, all written by me, and decently optimized:



Routine: Draw Alpha-coded sprite

inputs: pointer to data, x pos, y pos, width, height, alpha degree 1-255 (0 denotes no alpha value and normal drawing)

Code: [Select]
void AlphaSprite(short* data, int x, int y, int width, int height, char alpha) {
   short* VRAM = (short*)0xA8000000;
   int CurColor = 0;
   VRAM += (LCD_WIDTH_PX*y)+x;
   for(int j=y; j<y+height; j++) {
      for(int i=x; i<x+width;  i++) {
        CurColor = (*(VRAM) + (alpha*(*(data++))/256))/2;
        *(VRAM++) = CurColor % (65536);
      }
      VRAM += (LCD_WIDTH_PX-width);
   }
}



Generate pseudo-random number

input - 32bit integer for upper and lower bounds

this is based on the famous '128bit shifting' technique, and is considered highly random enough.

Code: [Select]
int Rand32(int lower, int upper) {
  static int a = 123456789;
  static int b = 362436069;
  static int c = 521288629;
  static int d = 88675123;
  int t;
 
  t = a ^ (a << 11);
  a = b;
  b = c;
  c = d;
  return (d = d ^ (d >> 19) ^ (t ^ (t >> 8)))%upper + lower;
}




Test a pixel of CURRENTLY rendered VRAM image (tari and Ashbad optimized)

inputs: X and Y position
outputs: short holding color value


Code: [Select]
short getpixel(short x, short y) {
    short *VRAM = (short *)0xA8000000;
    return *(VRAM + (y * LCD_WIDTH_PX) + x);
}




Invert Colors in Rectangular Area

inputs: shorts for x position, y position, length, and width
outputs: look at your screen!  8) (if you actually render it)

Code: [Select]
void InvArea(short x, short y, short height, short width)
   unsigned short *VRAM = (unsigned short *)0xA8000000;
   for(short a = 1; a>width; a++) {
      for(short b = 1; b>height; b++) {
         *(b + y * LCD_WIDTH_PX + a + x + (VRAM++)) ^= 0xFFFF;
      }
   }
}



Print Custom Character (improved)

inputs: an x position, a y position, a bit mapped image of the character, color to draw the character, if it is to draw a backcolor in non-mapped spaces, a short to specify backcolor (put 0 if DrawBackColor is false) , and the dimensions of the character
  EXAMPLE BIT MAPPED CHARACTER (the letter A):
          [0,0,1,0,0]
          [0,1,0,1,0]
          [0,1,1,1,0]
          [0,1,0,1,0]
          [0,1,0,1,0]
outputs: look at your screen :) (unless you don't render it)
       
       
       
Code: [Select]
void PutCustC(*bool map, short x, short y, short width, short height, short color, bool DrawBackColor, short backcolor) {
     short* VRAM = (short*)0xA8000000;
     VRAM += (LCD_WIDTH_PX * y) + x;
     for(short a = 0; a>width; a++) {
               for(short b = 0; b>height; b++) {
                         if(*(y + b * width + x + a + map)) { *(VRAM++) = color; }
                         elseif(DrawWhite) { *(VRAM++) = backcolor; }
                         else { VRAM++; }
               }
               VRAM += (LCD_WIDTH_PX-width);
     }
}



Draw Circle Routine

inputs: x, y, draw color and radius
outputs: look at your screen :) (that is, if you render it)

NOTE: uses a SetPoint routine in display_syscalls.h

Code: [Select]
void DrawCircle(short x0, short y0, short radius, short color)
{
  short f = 1 - radius;
  short ddF_x = 1;
  short ddF_y = -2 * radius;
  short x = 0;
  short y = radius;
 
  Bdisp_SetPoint_VRAM(x0, y0 + radius, color);
  Bdisp_SetPoint_VRAM(x0, y0 - radius, color);
  Bdisp_SetPoint_VRAM(x0 + radius, y0, color);
  Bdisp_SetPoint_VRAM(x0 - radius, y0, color);
 
  while(x < y)
  {
    // ddF_x == 2 * x + 1;
    // ddF_y == -2 * y;
    // f == x*x + y*y - radius*radius + 2*x - y + 1;
    if(f >= 0)
    {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;   
    Bdisp_SetPoint_VRAM(x0 + x, y0 + y, color);
    Bdisp_SetPoint_VRAM(x0 - x, y0 + y, color);
    Bdisp_SetPoint_VRAM(x0 + x, y0 - y, color);
    Bdisp_SetPoint_VRAM(x0 - x, y0 - y, color);
    Bdisp_SetPoint_VRAM(x0 + y, y0 + x, color);
    Bdisp_SetPoint_VRAM(x0 - y, y0 + x, color);
    Bdisp_SetPoint_VRAM(x0 + y, y0 - x, color);
    Bdisp_SetPoint_VRAM(x0 - y, y0 - x, color);
  }
}

EDIT: and I'm not sure where to put this, but here's a small yet useful update on the BFILE_syscalls.h header, with defines that more easily stand in place of a number for 'mode' in the Bfile_OpenFile_OS function.

Code: [Select]
#define O_READ 0x01
#define O_READ_SHARE 0x80
#define O_WRITE 0x02
#define O_READWRITE 0x03
#define O_READWRITE_SHARE 0x83

int Bfile_OpenFile_OS( const unsigned short*filename, int mode );
int Bfile_CloseFile_OS( int HANDLE );
int Bfile_ReadFile_OS( int HANDLE, void *buf, int size, int readpos );
int Bfile_CreateEntry_OS( const unsigned short*filename, int mode, int*size );
int Bfile_WriteFile_OS( int HANDLE, const void *buf, int size );
int Bfile_DeleteEntry( const unsigned short *filename );
void Bfile_StrToName_ncpy( unsigned short*dest, const unsigned char*source, int n );
« Last Edit: May 23, 2011, 05:02:55 pm by Ashbad »

Offline fxdev

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 177
  • Rating: +34/-6
    • View Profile
Re: Prizm Useful Routines -- post here!
« Reply #1 on: May 23, 2011, 03:44:55 pm »
Please, use Syscall 0x01E6 to obtain the VRAM address.
Interface: void *GetVRAMAddress(void);

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55942
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Prizm Useful Routines -- post here!
« Reply #2 on: May 23, 2011, 03:54:11 pm »
Thanks Ashbad for those routines. Hopefully they might be useful for some people here too. Some other people should post routines here too if they have any.
Now active at https://discord.gg/cuZcfcF (CodeWalrus server)

Ashbad

  • Guest
Re: Prizm Useful Routines -- post here!
« Reply #3 on: May 23, 2011, 04:12:59 pm »
Please, use Syscall 0x01E6 to obtain the VRAM address.
Interface: void *GetVRAMAddress(void);

I could, but since the address is known, it's a whole lot easier in many cases just to remember the magic number 0xA8000000 ;) however, good point brought up.

I just updated the first post at the bottom with an updated BFILE_syscalls.h header, which will prove to be very useful if you're opening any files at all.

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55942
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Prizm Useful Routines -- post here!
« Reply #4 on: May 23, 2011, 04:13:46 pm »
Could the address possibly change in future OS versions? I hope not....
Now active at https://discord.gg/cuZcfcF (CodeWalrus server)

Ashbad

  • Guest
Re: Prizm Useful Routines -- post here!
« Reply #5 on: May 23, 2011, 04:19:51 pm »
Could the address possibly change in future OS versions? I hope not....

From what I know, I don't think it would, then many other things would also get moved around, so I think for now we're safe :)

Offline AngelFish

  • Is this my custom title?
  • Administrator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3242
  • Rating: +270/-27
  • I'm a Fishbot
    • View Profile
Re: Prizm Useful Routines -- post here!
« Reply #6 on: May 23, 2011, 04:41:05 pm »
I see no reason why they couldn't change it, to be honest. All it would take is a change in the TLB code to move it. A few hundred bytes right or left isn't that much stuff to rearrange. They did that to make the Prizm OS, if anyone remembers.
« Last Edit: May 23, 2011, 04:41:42 pm by Qwerty.55 »
∂²Ψ    -(2m(V(x)-E)Ψ
---  = -------------
∂x²        ℏ²Ψ

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55942
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Prizm Useful Routines -- post here!
« Reply #7 on: May 23, 2011, 04:56:20 pm »
Yeah true. I just hope it won't change too much from an OS to another. Remember the mess when OS 2.53MP got released
Now active at https://discord.gg/cuZcfcF (CodeWalrus server)

Ashbad

  • Guest
Re: Prizm Useful Routines -- post here!
« Reply #8 on: May 23, 2011, 05:27:02 pm »
a few new routines, obviously ripped from somebody else and not by me, but however, I shall give full credit to the genius author of these awesome routines, prizmized by me.  EDIT: I was not able to easily convert a generic polygon-filling C routine to a decent Prizm-like format, so feel free to find/make your own :)

See if point is within bounds of a polygon

inputs:
int    polySides  =  how many corners the polygon has
float  polyX[]    =  horizontal coordinates of corners
float  polyY[]    =  vertical coordinates of corners
float  x, y       =  point to be tested

outputs:
returns if the point is within the bounds of the polygon.

Credit: many thanks to Darel Rex Finley, http://alienryderflex.com/polygon/



Code: [Select]
bool pointInPolygon(int polySides, float polyX[], float polyY[], float x, float y) {

  int      i, j=polySides-1 ;
  boolean  oddNodes=0      ;

  for (i=0; i<polySides; i++) {
    if (polyY[i]<y && polyY[j]>=y
    ||  polyY[j]<y && polyY[i]>=y) {
      if (polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])<x) {
        oddNodes=!oddNodes; }}
    j=i; }

  return oddNodes;
}

Offline fxdev

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 177
  • Rating: +34/-6
    • View Profile
Re: Prizm Useful Routines -- post here!
« Reply #9 on: May 23, 2011, 05:43:16 pm »
Quote
I could, but since the address is known, it's a whole lot easier in many cases just to remember the magic number 0xA8000000.

Quote
Could the address possibly change in future OS versions? I hope not....

They did this with OS 2.00 for the fx-9860G/GII back in 2009 and broke several hard-coded add-ins. So, do not rely on 0xA8000000.
« Last Edit: May 23, 2011, 05:45:54 pm by cfxm »

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55942
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Prizm Useful Routines -- post here!
« Reply #10 on: May 23, 2011, 05:47:20 pm »
Ouch this sucks. I think it would be best to avoid direct address usage then. I think this is what we do on some 83+ stuff.
Now active at https://discord.gg/cuZcfcF (CodeWalrus server)

Offline z80man

  • Casio Traitor
  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 977
  • Rating: +85/-3
    • View Profile
Re: Prizm Useful Routines -- post here!
« Reply #11 on: May 25, 2011, 04:54:08 am »
Please, use Syscall 0x01E6 to obtain the VRAM address.
Interface: void *GetVRAMAddress(void);
Due to my dislike of any syscalls I will just write a routine that does the exact same thing and polls the same address from ROM. It sounds foolish, but that is just the way I roll  8)

Note: I will go as far as file systems and text routines when it comes to avoiding syscalls.

List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)

Offline fxdev

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 177
  • Rating: +34/-6
    • View Profile
Re: Prizm Useful Routines -- post here!
« Reply #12 on: May 25, 2011, 07:00:16 am »
Okay, your decision but as long as a Prizm routine isn't buggy and fits my needs, I won't rewrite the whole thing.

Offline z80man

  • Casio Traitor
  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 977
  • Rating: +85/-3
    • View Profile
Re: Prizm Useful Routines -- post here!
« Reply #13 on: May 26, 2011, 10:36:58 am »
Alright I have a conversion from C to asm. It is get pixel and is as fast as possible and can be no more optimized. Unless gcc automatically handles the zero extension which I'll have to check.


Test a pixel of CURRENTLY rendered VRAM image (z80man optimized)

Code: (get pixel) [Select]
short GetPixel(short x, short y)
{
    MOV.W (width),R2
    MOV.L (VRAM),R3
    MULU.W r2,R5
    ADD R4,R3
    STS MACL,R2
    ADD R3,R2
    MOV.W @R2,R0
    RTS
    EXTU.W R0
    align.4
    width: word 384
    VRAM: long VRAM_address


List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)

Ashbad

  • Guest
Re: Prizm Useful Routines -- post here!
« Reply #14 on: May 26, 2011, 06:48:36 pm »
this is awesome :D I would suggest putting it into .s format so C coders can use it.