#include #include "swis.h" #include // SWI Registers extern _kernel_swi_regs inreg; extern _kernel_swi_regs outreg; extern unsigned char *buffer; extern unsigned char *fontbuffer; extern unsigned char *tilebuffer; char tilenamebuffer[4]; char letternamebuffer[2]; int screen = 1; int tilecache[256]; int lettercache[256]; extern void screen_nobuffer(); // Loads sprite file into buffer void load_sprites(char* filename, unsigned char **buffername) { int length; // Attempt to get file info inreg.r[0] = 5; inreg.r[1] = (int) filename; _kernel_swi(OS_File,&inreg,&outreg); // Length will be in R4 if it exists length = outreg.r[4]; // If it's <1 it's fil not found if(outreg.r[0] < 1) { printf("Sprite file %s not found, object type is %i and size is %i\n",filename,outreg.r[0],outreg.r[4]); exit(0); } // Stops us trying to mallocsomething mad if file is too big. if(length > 250000) { screen_nobuffer(); printf("Sprite file %s seems unreasonably large at %i bytes, object type is %i\n",filename, length, outreg.r[0]); exit(0); } // Attempt malloc, die if we cant *buffername = (unsigned char *) malloc(length + 4); if(buffername==NULL) { screen_nobuffer(); printf("Couldn't malloc %i bytes for sprite buffer\n",length); exit(0); } // Store size and other info as required for SpriteOp 9 to init sprite area *(unsigned int *)*buffername = length + 4; *(unsigned int *)(*buffername + 4) = 16; inreg.r[0] = 256+9; inreg.r[1] = (unsigned int) *buffername; _kernel_swi(OS_SpriteOp,&inreg,&outreg); // Load sprite file into buffer inreg.r[0] = 256+10; inreg.r[1] = (int) *buffername; inreg.r[2] = (int) filename; _kernel_swi(OS_SpriteOp,&inreg,&outreg); } void display_mode(int mode) { int pitch; int height=256; // TODO: This shouldn't be here! // OS_ScreenMode doesn't seem to work in 3.10 inreg.r[0] = 22; _kernel_swi(OS_WriteC,&inreg,&outreg); inreg.r[0] = mode; _kernel_swi(OS_WriteC,&inreg,&outreg); // The SDL library does this if double buffering is enabled - seems // to be what makes it work - although other examples dont have this inreg.r[0] = -1; inreg.r[1] = 6; _kernel_swi(OS_ReadModeVariable, &inreg, &outreg); pitch = outreg.r[2]; inreg.r[0] = 2; /* Screen area */ _kernel_swi(OS_ReadDynamicArea, &inreg, &outreg); inreg.r[1] = (pitch * height * 2) - outreg.r[1]; if (_kernel_swi(OS_ChangeDynamicArea, &inreg, &outreg) != NULL) { screen_nobuffer(); while(1) printf("Couldn't OS_ChangeDynamicArea\n"); exit(0); } } void draw_dotted_line(int x1,int y1,int x2,int y2) { inreg.r[0] = 4 + 16; inreg.r[1] = x1; inreg.r[2] = y1; _kernel_swi(OS_Plot,&inreg,&outreg); inreg.r[0] = 5 + 16; inreg.r[1] = x2; inreg.r[2] = y2; _kernel_swi(OS_Plot,&inreg,&outreg); } void draw_line(int x1,int y1,int x2,int y2) { inreg.r[0] = 4; inreg.r[1] = x1; inreg.r[2] = y1; _kernel_swi(OS_Plot,&inreg,&outreg); inreg.r[0] = 5; inreg.r[1] = x2; inreg.r[2] = y2; _kernel_swi(OS_Plot,&inreg,&outreg); } void draw_rectangle(int x1,int y1,int x2,int y2) { draw_line(x1,y1,x1,y2); draw_line(x1,y1,x2,y1); draw_line(x2,y2,x2,y1); draw_line(x2,y2,x1,y2); } int get_sprite_address(char* spritename) { inreg.r[0] = 256+24; inreg.r[1] = (int) buffer; inreg.r[2] = (int) spritename; _kernel_swi(OS_SpriteOp,&inreg,&outreg); if(outreg.r[2] == inreg.r[2]) outreg.r[2] = 0; return outreg.r[2]; } void draw_sprite_pointer(int pointer,int x, int y) { // Unable to look up address (or never tried) if(pointer == 0) return; // SpriteOp 34 to put sprite at a location inreg.r[0] = 512+34; inreg.r[1] = (int) buffer; inreg.r[2] = pointer; inreg.r[3] = x; inreg.r[4] = y; inreg.r[5] = 8; // GCOL dest=source and sprite mask _kernel_swi(OS_SpriteOp,&inreg,&outreg); } void draw_sprite(char* spritename,int x, int y) { // SpriteOp 34 to put sprite at a location inreg.r[0] = 256+34; inreg.r[1] = (int) buffer; inreg.r[2] = (int) spritename; inreg.r[3] = x; inreg.r[4] = y; inreg.r[5] = 8; // GCOL dest=source and sprite mask _kernel_swi(OS_SpriteOp,&inreg,&outreg); } void draw_sprite_flippedhv(char* spritename,int x, int y) { // SpriteOp 32 inreg.r[0] = 256+33; inreg.r[1] = (int) buffer; inreg.r[2] = (int) spritename; _kernel_swi(OS_SpriteOp,&inreg,&outreg); // SpriteOp 47 inreg.r[0] = 256+47; inreg.r[1] = (int) buffer; inreg.r[2] = (int) spritename; _kernel_swi(OS_SpriteOp,&inreg,&outreg); draw_sprite(spritename,x,y); // SpriteOp 47 inreg.r[0] = 256+47; inreg.r[1] = (int) buffer; inreg.r[2] = (int) spritename; _kernel_swi(OS_SpriteOp,&inreg,&outreg); // SpriteOp 32 inreg.r[0] = 256+33; inreg.r[1] = (int) buffer; inreg.r[2] = (int) spritename; _kernel_swi(OS_SpriteOp,&inreg,&outreg); } void draw_sprite_flippedh(char* spritename,int x, int y) { // SpriteOp 32 inreg.r[0] = 256+33; inreg.r[1] = (int) buffer; inreg.r[2] = (int) spritename; _kernel_swi(OS_SpriteOp,&inreg,&outreg); draw_sprite(spritename,x,y); // SpriteOp 32 inreg.r[0] = 256+33; inreg.r[1] = (int) buffer; inreg.r[2] = (int) spritename; _kernel_swi(OS_SpriteOp,&inreg,&outreg); } void draw_sprite_flippedv(char* spritename,int x, int y) { // SpriteOp 47 inreg.r[0] = 256+47; inreg.r[1] = (int) buffer; inreg.r[2] = (int) spritename; _kernel_swi(OS_SpriteOp,&inreg,&outreg); draw_sprite(spritename,x,y); // SpriteOp 47 inreg.r[0] = 256+47; inreg.r[1] = (int) buffer; inreg.r[2] = (int) spritename; _kernel_swi(OS_SpriteOp,&inreg,&outreg); } int get_letter_address(int letternumber) { if(lettercache[letternumber] > 0) return lettercache[letternumber]; sprintf(letternamebuffer,"%c",letternumber); inreg.r[0] = 256+24; inreg.r[1] = (int) fontbuffer; inreg.r[2] = (int) letternamebuffer; _kernel_swi(OS_SpriteOp,&inreg,&outreg); // For now, if we get an invalid character just display an X // to make it really obvious if(outreg.r[2] == inreg.r[2]) get_letter_address((int)'X'); lettercache[letternumber] = outreg.r[2]; return lettercache[letternumber]; } void draw_letter(int letter,int x, int y) { int address = get_letter_address(letter); // SpriteOp 34 to put sprite at a location inreg.r[0] = 512+34; inreg.r[1] = (int) fontbuffer; inreg.r[2] = address; inreg.r[3] = x; inreg.r[4] = y; inreg.r[5] = 8; _kernel_swi(OS_SpriteOp,&inreg,&outreg); } int get_tile_address(int tilenumber) { if(tilecache[tilenumber] > 0) return tilecache[tilenumber]; sprintf(tilenamebuffer,"%i",tilenumber); inreg.r[0] = 256+24; inreg.r[1] = (int) tilebuffer; inreg.r[2] = (int)tilenamebuffer; _kernel_swi(OS_SpriteOp,&inreg,&outreg); // Show default tile if not found if(outreg.r[2] == inreg.r[2]) { get_tile_address(0); } // Caching 0 seems to make it shit itself? if(tilenumber > 0) tilecache[tilenumber] = outreg.r[2]; return outreg.r[2]; } void draw_tile(int tilenumber,int x, int y) { int address = get_tile_address(tilenumber); // SpriteOp 34 to put sprite at a location inreg.r[0] = 512+34; inreg.r[1] = (int) tilebuffer; // unused because pointers are in use now inreg.r[2] = address; inreg.r[3] = x; inreg.r[4] = y; inreg.r[5] = 0; _kernel_swi(OS_SpriteOp,&inreg,&outreg); } void draw_tile_trans(int tilenumber,int x, int y) { int address = get_tile_address(tilenumber); // SpriteOp 34 to put sprite at a location inreg.r[0] = 512+34; inreg.r[1] = (int) tilebuffer; inreg.r[2] = address; inreg.r[3] = x; inreg.r[4] = y; inreg.r[5] = 8; _kernel_swi(OS_SpriteOp,&inreg,&outreg); } void draw_spritetext(char* text, int x, int y) { int currentx; int currenty; int i; currentx = x; currenty = y; for(i = 0; i < strlen(text); i++) { if((text[i] != ' ') && (text[i] != '\n') && (text[i] != '~')) draw_letter(text[i],currentx,currenty); switch (text[i]) { case 't': case 'i': case '.': case ',': case 'y': case ':': currentx += 12 + 4; break; case '\'': currentx += 8 + 4; break; case 'm': currentx += 22 + 4; break; case 'q': case 'w': currentx += 20 + 4; break; case ' ': case '(': case ')': currentx += 8 + 4; break; case '=': currentx += 22 + 2; break; case '{': case '}': case ']': currentx += 26; break; case '~': currentx -= 2; break; default: currentx += 16 + 4; } if(text[i] == '\n') { currentx = x; currenty -= 36; } } } void draw_text(char* text, int x, int y, int fonthandle) { inreg.r[0] = fonthandle; inreg.r[1] = (int) text; inreg.r[2] = 1 << 4; inreg.r[3] = x; inreg.r[4] = y; inreg.r[5] = 0; inreg.r[6] = 0; inreg.r[7] = 0; _kernel_swi(Font_Paint,&inreg,&outreg); } int font_find(char* font, int height, int width) { inreg.r[0] = 0; inreg.r[1] = (int) font; inreg.r[2] = height*16; inreg.r[3] = width*16; inreg.r[4] = 0; inreg.r[5] = 0; _kernel_swi(Font_FindFont,&inreg,&outreg); return outreg.r[0]; } void font_colour(int fg, int bg, int fonthandle) { inreg.r[0] = fonthandle; inreg.r[1] = bg; inreg.r[2] = fg; inreg.r[3] = 14; _kernel_swi(ColourTrans_SetFontColours, &inreg, &outreg); } void graphics_colour(int setcolour) { inreg.r[0] = setcolour; inreg.r[1] = -1; inreg.r[2] = 0; _kernel_swi(ColourTrans_ReturnColourNumberForMode,&inreg,&outreg); inreg.r[0] = 0; inreg.r[1] = outreg.r[0]; _kernel_swi(OS_SetColour,&inreg,&outreg); } void screen_flipbuffer() { // Hardware inreg.r[0] = 113; inreg.r[1] = screen+1; _kernel_swi(OS_Byte,&inreg,&outreg); screen ^= 1; // Drivers inreg.r[0] = 112; inreg.r[1] = screen+1; _kernel_swi(OS_Byte,&inreg,&outreg); inreg.r[0] = 19; _kernel_swi(OS_Byte,&inreg,&outreg); } void screen_nobuffer() { // Hardware inreg.r[0] = 113; inreg.r[1] = 1; _kernel_swi(OS_Byte,&inreg,&outreg); // Drivers inreg.r[0] = 112; inreg.r[1] = 1; _kernel_swi(OS_Byte,&inreg,&outreg); inreg.r[0] = 19; _kernel_swi(OS_Byte,&inreg,&outreg); } void screen_clear() { inreg.r[0] = 12; _kernel_swi(OS_WriteC,&inreg,&outreg); }