#include "platform.h" #include "event.h" #include "opcodeInfo.h" int running=1; int error=0; int Platform_running() { return running; } void Platform_setError(int err) { error=err; } int Platform_getError() { return error; } #if defined(PC) #include #include //BEGIN SDL handling #include #include "keyboard.h" #define ZOOM 4 //prepare variables SDL_Window *window; SDL_Renderer *renderer; SDL_Rect rect={.w=ZOOM, .h=ZOOM}; //create our own vram and screen buffers char vram[VRAM_LENGTH]; char screen[VRAM_LENGTH]; //macros to draw to screen #define white() SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE) #define black() SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE) #define pixel(x, y) do {rect.x=x*ZOOM; rect.y=y*ZOOM; SDL_RenderFillRect(renderer, &rect);} while(0) void sdlInit() { //create a window SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER); SDL_CreateWindowAndRenderer(VRAM_WIDTH*ZOOM, VRAM_HEIGHT*ZOOM, 0, &window, &renderer); //clear the window white(); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); } void sdlQuit() { //destroy everything and quit SDL SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); } char* Graph_getVramAddress() { return vram; } void printScreen() { for(unsigned char y=0; y>(8-bit-1))&0x01; //set the color accordingly if(value) black(); else white(); //and print this now pixel(x, y); } } SDL_RenderPresent(renderer); } void Graph_printVram() { //copy the VRAM into the screen buffer and then display it for(int i=0; itype==SDL_QUIT) running=0; //redraw the window if it gets exposed if(event->type==SDL_WINDOWEVENT&&event->window.event==SDL_WINDOWEVENT_EXPOSED) printScreen(); //if it's a keyboard event, handle it if(event->type==SDL_KEYDOWN||event->type==SDL_KEYUP) { event_t evt={ .type=EVENT_TYPE_KEYBOARD, .subtype=event->type==SDL_KEYDOWN?EVENT_TYPE_KEYBOARD_PRESS:EVENT_TYPE_KEYBOARD_RELEASE }; evt.keyevent.repeat=event->key.repeat; evt.keyevent.code=Keyboard_getCode(event->key.keysym.sym); if(evt.keyevent.code!=-1) Event_put(&evt); } //if it's a timer event(using USEREVENT as a convinience), handle it if(event->type==SDL_USEREVENT) { event_t evt={ .type=EVENT_TYPE_TIMER, .subtype=0 }; evt.timerevent.code=event->user.code; Event_put(&evt); } } void sdlTick(int block) { SDL_Event event; if(block) { //block until we have an event if(SDL_WaitEvent(&event)) sdlEvt(&event); } //iterate all pending events while(SDL_PollEvent(&event)) sdlEvt(&event); } //END SDL handling #endif #if defined(LINUX) #include #include #include #include //BEGIN file handling #define MAX_FILES 256 typedef struct file_info_t { int fd; int offset; int mode; } file_info_t; int fileCount=0; file_info_t files[MAX_FILES]; //check if a file is opened int checkFile(int fd) { for(int i=0; i=0x0101||keycode==0x0000) matcode=keycode; else if(keycode!=34) { matcode=(keycode/10-1)<<8; matcode|=keycode%10; } return ((*(sc_i_sp)sc_isKeyPressed)(&matcode));*/ } void printVram() { (*(sc_v_v)sc_printVram)(); } void* getVramAddress() { return ((*(sc_vp_v)sc_getVramAddress)()); } //END syscalls //BEGIN graphical functions char* Graph_getVramAddress() { return getVramAddress(); } void Graph_printVram() { printVram(); } //END graphical functions //BEGIN file functions //get the file path FONTCHARACTER path[32]; FONTCHARACTER* getPath(char* filename) { char* str="\\\\fls0\\"; for(int i=0; i<32; i++) path[i]='\0'; for(int i=0; i<7; i++) path[i]=str[i]; int len=strlend(filename); for(int i=0; i<=len; i++) path[i+7]=filename[i]; return path; } //fuck CASIO for making me do this! //store information on the files int deleteFile(int fd); int lastFd; typedef struct file_info_t { int fd; int handle; int length; char mode; FONTCHARACTER path[32]; char* buffer; } file_info_t; file_info_t* files=0; int fileInit() { files=calloc(32, sizeof(file_info_t)); lastFd=1; return files!=0; } int fileQuit() { for(int i=0; i<32; i++) { if(files[i].fd) deleteFile(files[i].fd); } free(files); return 1; } //get free space int getFreeFile() { for(int i=0; i<32; i++) { if(files[i].fd==0) return i; } return -1; } //create a file information int openFile(char* path, int mode) { //check if we have enough room for files int spot=getFreeFile(); if(spot==-1) return -100; //store info here file_info_t info; info.fd=lastFd++; info.mode=mode; info.buffer=0; info.handle=-1; //set path FONTCHARACTER* fPath=getPath(path); for(int i=0; i<32; i++) info.path[i]=fPath[i]; if(mode&FILE_OPEN_read) { //read file size int len=0; int handle=Bfile_OpenFile(info.path, _OPENMODE_READ); if(handle>=0) len=Bfile_GetFileSize(handle); else return handle; info.length=len>=0?len:0; //read file data if(len&&handle) { char* ptr=malloc(len); info.buffer=ptr; if(!ptr) { Bfile_CloseFile(handle); return -200; } int val=Bfile_ReadFile(handle, ptr, len, 0); if(val<0) { free(ptr); Bfile_CloseFile(handle); return val; } } } else { info.length=0; info.buffer=0; } //add the file to the list files[spot]=info; //return the fd return info.fd; } //retrieve a file information int getFile(int fd, file_info_t *info) { for(int i=0; i<32; i++) { *info=files[i]; if(info->fd==fd) return 1; } return 0; } void putFile(int fd, file_info_t *info) { for(int i=0; i<32; i++) { if(info->fd==fd) { files[i]=*info; return; } } } //returns the mode int getMode(int mode) { if((mode&FILE_OPEN_read)&&(mode&FILE_OPEN_write)) return _OPENMODE_READWRITE; else if(mode&FILE_OPEN_write) return _OPENMODE_WRITE; return _OPENMODE_READ; } //delete a file information int deleteFile(int fd) { for(int i=0; i<32; i++) { if(files[i].fd==fd) { file_info_t info=files[i]; //close the file if it is already open if(info.handle) { Bfile_CloseFile(info.handle); info.handle=0; } //if the file is not empty int err=0; if(info.length) { if(!info.buffer) err=-101; //create it if absent Bfile_DeleteFile(info.path); int create=Bfile_CreateFile(info.path, info.length); if(create&&!err) err=create; //write data to file info.handle=Bfile_OpenFile(info.path, getMode(info.mode)); if(info.handle<0) err=info.handle; int len=Bfile_WriteFile(info.handle, info.buffer, info.length); if(len<0&&!err) err=len; int close=Bfile_CloseFile(info.handle); if(close<0&!err) err=close; } //free the buffer if(info.buffer) free(info.buffer); //some checks if(info.length<0) err=-102; if((info.mode&FILE_OPEN_write)&&!info.length) err=-103; // remove the data info.fd=0; files[i]=info; return err; } } return -100; } int File_open(char* path, int mode) { return openFile(path, mode); } int File_close(int fd) { return deleteFile(fd); } int File_read(int fd, int pos, void* buffer, int len) { //get file and check the position file_info_t info; if(!getFile(fd, &info)) return -1; if(pos<0||len<0) return -2; if(pos+len>info.length) len=info.length; //if we have the file in a buffer, read from the buffer if(info.buffer) { char* ptr=(char*) buffer; for(int i=0; isize) { info.length=size; putFile(fd, &info); return 0; } else { char* newptr=realloc(info.buffer, size); if(newptr) { info.length=size; info.buffer=newptr; putFile(fd, &info); return 0; } return -4; } } else { info.buffer=calloc(1, size); if(!info.buffer) return -3; info.length=size; putFile(fd, &info); return 0; } } int File_delete(char* path) { if(!Bfile_DeleteFile(getPath(path))) return 0; return Bfile_DeleteDirectory(getPath(path)); } int File_mkdir(char* path) { return Bfile_CreateDirectory(getPath(path)); } //END file functions //BEGIN timer-related functions #define KEY_TIMER 1 #define KEY_DELAY 50 #define KEY_COUNT 50 typedef struct key_info_t { char code; char time; //short matcode; } key_info_t; key_info_t keys[KEY_COUNT]; #include "test.h" void keyHandle(int pos) { event_t evt={ .type=EVENT_TYPE_KEYBOARD, .keyevent={ .code=keys[pos].code, .repeat=0 } }; // check the old status of the key if(keys[pos].time) { // check if the key is still down if(isKeyDown(keys[pos].code)) { // first repeat is after 10 periods, so 500ms or 1/2sec if(keys[pos].time==10) { evt.subtype=EVENT_TYPE_KEYBOARD_PRESS; evt.keyevent.repeat=1; Event_put(&evt); // repeat event every 4 periods, so 200ms or 1/5sec keys[pos].time-=4; } // increment key time counter keys[pos].time++; } else { // detect key release evt.subtype=EVENT_TYPE_KEYBOARD_RELEASE; Event_put(&evt); keys[pos].time=0; } } else if(isKeyDown(keys[pos].code)) { // set the key status to pressed evt.subtype=EVENT_TYPE_KEYBOARD_PRESS; Event_put(&evt); keys[pos].time=1; } } void keyHandler() { for(int i=0; i