Is there a getkey routine that allows multiple keys to be checked for being pressed at the exact same time? Such as, it returns an array of all the keys, and you could do something like this?


Code:
char key[];
...
key = GetKeyASDF();
if(key[KEY_PRGM_RIGHT]&&key[KEY_PRGM_SHIFT]) { ... }


I noticed Kerm's new routine for key reading seems to work with key rows and key columns, and the other one that was non-blocking used some sort of "unsigned char buffer[12]" against which to check for key values, that was condensed into one "key" value. Would I be able to check rows/columns or parts of that small buffer for multiple keys at the same time?
I'm not sure if/how this answers your question, so please feel free to follow up. I don't know a way of doing simultaneous key detection, but I do know a way to do non-blocking input that doesn't mess up colors. For example, from Tetrizm:


Code:
            if (0 != GetKeyWait_OS(&kcol,&krow,KEYWAIT_HALTOFF_TIMEROFF,1,0,&key)) {
               //key was returned

               int newpiecex = curpiecex;
               if (kcol == 2 && krow == 9 && curpiecex > 0) newpiecex--;
               if (kcol == 3 && krow == 8 && curpiecex < GRID_WIDTH-width) newpiecex++;
               if (kcol == 4 && krow == 9) {
                  gameactive = 0;
                  goto finishgamefree;
               }
Unfortunately, The color issue is far less important to my game than multi-key detection Sad thanks anyways, though.
Ashbad wrote:
Unfortunately, The color issue is far less important to my game than multi-key detection Sad thanks anyways, though.
You misunderstand me, you can do the color fix with any of the input methods, but the WaitKeyOS method is much faster and can handle the MENU key sanely.
Ah, okay then, thanks for the method then Smile for that routine, will I have to check the keyrow and keycolumn for each key, or can I just just use the key variable it returns?

Also, just for fun documentation (not sure if anyone knew yet), but the OS_InnerWait_ms routine can only work with values under ~1000 (maybe up to 1024 or something, but something like 1100 doesn't work); any higher values don't pause for the milliseconds given, but rather for more like ~5 milliseconds. EDIT: Just shared it because I just tested with it Smile For doing something like pausing for 2.5 seconds, you would use it like:


Code:

   OS_InnerWait_ms(1000);
   OS_InnerWait_ms(1000);
   OS_InnerWait_ms(480); // just for possible calling lag
Hi, I just registered to reply here, that I've write a function to detect multiple-keys pressing.


Code:
int keydown(int basic_keycode)
{
   const unsigned short* keyboard_register = (unsigned short*)0xA44B0000;
   int row, col, word, bit;
   row = basic_keycode%10;
   col = basic_keycode/10-1;
   word = row>>1;
   bit = col + 8*(row&1);
   return (0 != (keyboard_register[word] & 1<<bit));
}

Expect a Basic keycode (27=right, 38=left) or 10 to test the AC/ON key, and return 1 if pressed, 0 if not.
It allow to detect multiple pressed keys simultaneous.
PierrotLL wrote:
Hi, I just registered to reply here, that I've write a function to detect multiple-keys pressing.


Code:
...

Expect a Basic keycode (27=right, 38=left) or 10 to test the AC/ON key, and return 1 if pressed, 0 if not.
It allow to detect multiple pressed keys simultaneous.
Hey, that's great! Thanks a lot for this, very helpful. Do you have any more useful routines?
PierrotLL wrote:
It allow to detect multiple pressed keys simultaneous.


You have no idea how much I needed this. Thanks! Very Happy Is non-blocking, too?

Also, are there defines for the key combinations in the SDK's "keyboard.hpp" file that correspond to Prizm BASIC keycodes?
PierrotLL, welcome to Cemetech! I hope you'll stick around to share your Prizm experience with us, as well as any projects you're currently working on or are planning. Might I also request that you Introduce Yourself?
merthsoft wrote:
Do you have any more useful routines?
Soon, I will Razz

Ashbad wrote:
Is non-blocking, too?
Yes, it just read the key matrix, so it's really fast.

Ashbad wrote:
Also, are there defines for the key combinations in the SDK's "keyboard.hpp" file that correspond to Prizm BASIC keycodes?
You can use the constants starting with "KEY_PRGM_" of "keyboard.hpp"

@KermMartian : Thanks, I go write a little post on your topic Smile
PierrotLL wrote:
Ashbad wrote:
Also, are there defines for the key combinations in the SDK's "keyboard.hpp" file that correspond to Prizm BASIC keycodes?
You can use the constants starting with "KEY_PRGM_" of "keyboard.hpp"


Awesome, so I don't even need to change much in my code except for key debouncing and allowing multiple key checks Smile Thanks again for the routine!
Thanks so much for this, PierrotLL! The routine works perfectly and adds sooo much to my game Very Happy
_player1537 wrote:
Thanks so much for this, PierrotLL! The routine works perfectly and adds sooo much to my game Very Happy


Same with me Smile I had to change it around some for the purpose I needed (being able to check for onkeydown pseudo-events, and onkeyup pseudo-events), but I wouldn't be able to do anything without the original routine.
Pierrot, obviously it doesn't do debouncing or the odd little OS functionality of the [MENU] key, but that would be easy enough to do in other ways if needed. Thanks for sharing this, and I of course look forward to your further contributions.
my fixed file routines:

Code:
#define close_file(handle) Bfile_CloseFile_OS(handle)
typedef int file;

file make_file(char*name, int size) {
    unsigned char*n = malloc(256*sizeof(unsigned short));
    unsigned short*n2 = malloc(strlen(name)+7*sizeof(char));
    *(sizeof(char)*7+strlen(name)+n+1) = 0x00;
    memcpy(n, "\\\\fls0\\", 7*sizeof(char));
    memcpy(sizeof(char)*7+n, name, strlen(name));
    Bfile_StrToName_ncpy(n2, n, strlen((char*)n));
    free(n);
    name = (char*) n2;
    free(n2);
    Bfile_CreateEntry_OS(n2, 0x1, &size);
    return Bfile_OpenFile_OS(n2, 0x3);
}

void*read_file(file handle, int size, int offset) {
    static char*buf;
   buf = malloc(size);
    Bfile_ReadFile_OS(handle, buf, size, offset);
    return buf;
}

void write_file(file handle, int size, int offset, void*data) {
    char*buffer = malloc(size+offset);
    memcpy(buffer, read_file(handle, offset, 0), offset);
    memcpy(buffer+offset, data, size);
    Bfile_WriteFile_OS(handle, buffer, size+offset);
    free(buffer);
}

int file_exists(char*name) {
    unsigned char*n = malloc(256*sizeof(unsigned short));
    unsigned short*n2 = malloc(strlen(name)+7*sizeof(char));
    *(sizeof(char)*7+strlen(name)+n+1) = 0x00;
    memcpy(n, "\\\\fls0\\", 7*sizeof(char));
    memcpy(sizeof(char)*7+n, name, strlen(name));
    Bfile_StrToName_ncpy(n2, n, strlen((char*)n));
    free(n);
    name = (char*) n2;
    free(n2);
    file exists = Bfile_OpenFile_OS(n2, 0x3);
    close_file(exists);
    return (exists>=0);
}

int strlen(char*a) {
   int c = 0;
   while(*(a+c)) { c++; }
   return c;
}
Ashbad wrote:

Code:
void*read_file(file handle, int size, int offset) {
    static char*buf;
   buf = malloc(size);
    Bfile_ReadFile_OS(handle, buf, size, offset);
    return buf;
}

void write_file(file handle, int size, int offset, void*data) {
    char*buffer = malloc(size+offset);
    memcpy(buffer, read_file(handle, offset, 0), offset);
    memcpy(buffer+offset, data, size);
    Bfile_WriteFile_OS(handle, buffer, size+offset);
    free(buffer);
}

Holy leaky functions, batman! Smile
write_file doesn't free the memory allocated by read_file, and the pointer to the memory isn't saved anywhere to free it later. Does the Bfile_WriteFile_OS function/syscall really require the programmer to rewrite the entire beginning contents of the file even to write a single byte somewhere in the middle of the file? I would think that the syscall would keep track of the current write position like fwrite and write (the POSIX system interface). In fact the prototype looks practically the same as for write:

Code:
ssize_t write(int filed, void *buf, size_t count);

Of course, I could be wrong, and it might be a braindead syscall after all.
christop wrote:

Holy leaky functions, batman! Smile


Yep, I typed them one night at Catherine's request on my iPad in about 5 minutes, so they were bound to be criticized for that Razz


Quote:
Does the Bfile_WriteFile_OS function/syscall really require the programmer to rewrite the entire beginning contents of the file even to write a single byte somewhere in the middle of the file? I would think that the syscall would keep track of the current write position like fwrite and write (the POSIX system interface). In fact the prototype looks practically the same as for write:
Code:
ssize_t write(int filed, void *buf, size_t count);

Of course, I could be wrong, and it might be a braindead syscall after all.


Yep, the syscalls really are that horribly brain-dead, unfortunately Sad
Ashbad wrote:
Quote:
Does the Bfile_WriteFile_OS function/syscall really require the programmer to rewrite the entire beginning contents of the file even to write a single byte somewhere in the middle of the file? I would think that the syscall would keep track of the current write position like fwrite and write (the POSIX system interface). In fact the prototype looks practically the same as for write:
Code:
ssize_t write(int filed, void *buf, size_t count);

Of course, I could be wrong, and it might be a braindead syscall after all.


Yep, the syscalls really are that horribly brain-dead, unfortunately Sad

Interesting. I just read some of the official SDK documentation (found at http://prizmwiki.omnimaga.org/wiki/Tools#Official_Casio_SDK), and here's what it says about Bfile_WriteFile:
Quote:
The Bfile_WriteFile function writes data to a file. The function starts writing data to the file at the position
indicated by the file pointer. After the write operation has been completed, the file pointer is adjusted by the
number of bytes actually written.
...
Return Values
If the function succeeds, this function returns the position indicated by the file pointer. It is greater than or equal to
0.
If the function fails, the return value is an error code. It is a negative value.

So it seems to me that it does keep track of the current file position.

Since (on the Prizm) int is the same size as long (and therefore the same size as size_t and ssize_t), you can almost use this syscall as a drop-in replacement for the standard write syscall. The only difference is the return value. write returns the number of bytes written, whereas Bfile_WriteFile returns the file position. Here's a possible wrapper to get more or less the same functionality as write:

Code:
ssize_t write(int fd, const void *buf, size_t count)
{
    int pos1 = Bfile_WriteFile(fd, NULL, 0); // get the current position
    int pos2 = Bfile_WriteFile(fd, buf, count);
    if (pos2 < 0) {
        // this should also set errno
        return -1;
    }
    return pos2 - pos1;
}

// just for kicks, here's read:
ssize_t read(int fd, const void *buf, size_t count)
{
    int n = Bfile_ReadFile(fd, buf, count);
    // Bfile_ReadFile returns the number of bytes read
    // which is inconsistent with Bfile_WriteFile. Silly Casio!
    if (n < 0) {
        // this should also set errno
        return -1;
    }
    return n;
}

From there it should be fairly straightforward to implement or port a stdio using write and read. Unfortunately, it might be a challenge to implement lseek (on which fseek depends) as the Bfile_SeekFile syscall is limited in how it moves the file position. The documentation isn't even clear on how it does move the file position either (ie, is it absolute or relative to the current position?). It may be necessary to keep track of the file position in stdio in order to properly support lseek/fseek, but this is lame because it violates the Don't Repeat Yourself (DRY) principle.

EDIT: It might not be necessary to keep track of the file position in stdio after all:

Code:
off_t lseek(int fildes, off_t offset, int whence)
{
    switch (whence) {
    case SEEK_SET:
        break;
    case SEEK_CUR:
        offset += Bfile_WriteFile(fd, NULL, 0); // add current offset
        break;
    case SEEK_END:
        offset += Bfile_GetFileSize(fd); // add file size
        break;
    default:
        return -1;
    }
    if (offset < 0) {
        return -1;
    }
    Bfile_SeekFile(fd, offset);
    return offset;
}

(This code does little error checking and assumes that Bfile_SeekFile sets the file position absolutely).
Well, I'm unsure if anyone's shared it yet, but here's the optimized version of Kerm's two sprite routines:


Code:
void CopySprite(const void* datar, int x, int y, int width, int height) {
   color_t*data = (color_t*) datar;
   color_t* VRAM = (color_t*)0xA8000000;
   VRAM += LCD_WIDTH_PX*y + x;
   for(int j=y; j<y+height; j++) {
      for(int i=x; i<x+width; i++) {
         *(VRAM++) = *(data++);
     }
     VRAM += LCD_WIDTH_PX-width;
   }
}

void CopySpriteMasked(const void*datar, int x, int y, int width, int height, int maskcolor) {
   color_t*data = (color_t*) datar;
   color_t* VRAM = (color_t*)0xA8000000;
   VRAM += LCD_WIDTH_PX*y + x;
   for(int j=y; j<y+height; j++) {
      for(int i=x; i<x+width;  i++) {
         if (*(data) != maskcolor) {
            *(VRAM++) = *(data++);
         } else { VRAM++; data++; }
      }
      VRAM += LCD_WIDTH_PX-width;
   }
}


Same as the original, but faster (literally, the only optimization done is moving by halfwords instead of bytes).

And, for a simple routine that clears the screen to any given color, very very fast, here's this that I use (a lot faster than all of the syscalls that do similar or the same):


Code:
void fill_scr(color_t color) {
        unsigned int temp_color = (unsigned int)(color<<16) | color;
   for(int i = 0; i < LCD_WIDTH_PX*LCD_HEIGHT_PX/2; i++) {
      *((int*)0xA8000000+i) = temp_color;
   }
}
Very nice. Is "maskcolor" the same as transparency?
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
» Goto page Previous  1, 2, 3, 4, 5, 6 ... 10, 11, 12  Next
» View previous topic :: View next topic  
Page 5 of 12
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement