Files
CTheEscape/!TheEsc/c/Graphics
T
2021-03-26 22:08:25 +00:00

203 lines
4.4 KiB
Plaintext

#include <stdio.h>
#include "swis.h"
#include <kernel.h>
// SWI Registers
extern _kernel_swi_regs inreg;
extern _kernel_swi_regs outreg;
extern unsigned char *buffer;
int screen = 1;
// Loads sprite file into buffer
void load_sprites(char* filename)
{
int length;
// Attempt to get file info
inreg.r[0] = 13;
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",filename);
exit(0);
}
// Stops us trying to mallocsomething mad if file is too big.
if(length > 200000)
{
printf("Sprite file %s seems unreasonably large at %i bytes",filename, length);
exit(0);
}
// Attempt malloc, die if we cant
buffer = (unsigned char *) malloc(length + 4);
if(buffer==NULL)
{
printf("Couldn't malloc %i bytes for sprite buffer",length);
exit(0);
}
// Store size and other info as required for SpriteOp 9 to init sprite area
*(unsigned int *)buffer = length + 4;
*(unsigned int *)(buffer + 4) = 16;
inreg.r[0] = 256+9;
inreg.r[1] = (unsigned int) buffer;
_kernel_swi(OS_SpriteOp,&inreg,&outreg);
// Load sprite file into buffer
inreg.r[0] = 256+10;
inreg.r[1] = (int) buffer;
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)
{
printf("Couldn't OS_ChangeDynamicArea");
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);
}
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_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_clear()
{
inreg.r[0] = 12;
_kernel_swi(OS_WriteC,&inreg,&outreg);
}