home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
141.lha
/
C64_Emulator
/
screen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-21
|
8KB
|
388 lines
/*
* Commodore 64 Spoof Emulator (C) Eddy Carroll, 1st April 1988
*
* Module: SCREEN.C
*
* This module contains the various screen handling routines used by
* the emulator.
*
*/
#define SCREEN
#include <exec/types.h>
#include <exec/io.h>
#include <intuition/intuition.h>
#include "screen.h"
struct RastPort *rp;
int openconsole = 0;
struct NewScreen NewScreen = {
0,0,320,200, /* Screen position & size */
2, /* 2 bitplanes = 4 colours */
0,1, /* Default text colours */
0, /* Lores, non-interlace */
CUSTOMSCREEN, /* Screen type */
0, /* Use default font for now */
"C64 Emulator", /* Screen title */
0, /* No gadgets */
0 /* No custom bitmap */
};
#define NORMALFLAGS WINDOWCLOSE | WINDOWSIZING | WINDOWDEPTH | WINDOWDRAG
struct NewWindow NewWindow = {
0,0,320,200, /* Window position & Size */
0,1, /* Default text colours */
MENUPICK | /* Ok, we want to know */
INTUITICKS, /* about menus & timings */
BACKDROP | /* These four flags define */
BORDERLESS | /* the type of window we */
ACTIVATE | /* open. Here, we want an */
0 , /* "invisible" window. */
NULL, /* No gadgets */
NULL, /* Default menus check mark */
NULL, /* No window title */
NULL, /* Will point to our screen */
NULL, /* No special bitmap used */
0,0,320,200, /* No resizing so not used */
CUSTOMSCREEN /* Open this on OUR screen */
};
UWORD blackcol[4] = { /* All black array for initial screen */
0,0,0,0};
UWORD screencol[4] = { /* Default colours for custom screen */
0x077E, /* Colour 0 = Light blue */
0x0EEE, /* Colour 1 = White */
0x077E, /* Colour 2 = Lighter blue */
0x011C /* Colour 3 = Dark Blue */
};
struct IntuiText mytext[] = {
/* Pens Mode Pos Font Text Next */
{ 0,1, JAM1, 0,0, NULL, (UBYTE *)" About...", NULL},
{ 0,1, JAM1, 0,0, NULL, (UBYTE *)" Show Title", NULL},
{ 0,1, JAM1, 0,0, NULL, (UBYTE *)" Quit", NULL}};
#define MENUFLAGS ITEMTEXT | ITEMENABLED | HIGHCOMP
#define IDATA(off,str,key) 0,off,110,9,MENUFLAGS,0,str,NULL,key,NULL,NULL
struct MenuItem myitems[] = {
{ &myitems[1], IDATA( 0, (APTR)&mytext[0], M_ABOUT) },
{ &myitems[2], IDATA(10, (APTR)&mytext[1], M_TITLE) },
{ NULL, IDATA(20, (APTR)&mytext[2], M_QUIT ) }};
struct Menu mymenus = {NULL, 0,0,100,10, MENUENABLED, "Project", myitems};
/*
* Free all resources allocated in this module
*
*/
void cleanup(err)
int err;
{
if (openconsole)
CloseDevice(ConReadReq);
if (ConReadReq)
DeleteStdIO(ConReadReq);
if (ConReadPort)
DeletePort(ConReadPort);
if (mywin) {
ClearMenuStrip(mywin);
CloseWindow(mywin);
}
if (myscreen)
CloseScreen(myscreen);
if (IntuitionBase)
CloseLibrary(IntuitionBase);
if (GfxBase)
CloseLibrary(GfxBase);
exit(err);
}
/*
* Clears the screen
*
*/
void clearscreen()
{
register char *p;
register int i;
SetRast(rp,3);
for (p = (char *)screen, i = 1000; i--; *p++ = ' ')
;
cursorx = 0;
cursory = 0;
}
/*
* Tells console device we want to read a character from keyboard
*
*/
void QueueRead(request,whereto)
struct IOStdReq *request;
char *whereto;
{
request->io_Command = CMD_READ;
request->io_Data = (APTR)whereto;
request->io_Length = 1;
SendIO(request);
}
/*
* Initialises the screen, character set, colours etc. Exits program with
* error code if an error occurs.
*
*/
void initscreen()
{
if (!mywin) {
if ((IntuitionBase =
(struct IntuitionBase *)OpenLibrary("intuition.library",0)) == 0)
cleanup(1);
if ((GfxBase =
(struct GfxBase *)OpenLibrary("graphics.library",0)) == 0)
cleanup(2);
if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == 0)
cleanup(3);
LoadRGB4(&(myscreen->ViewPort),blackcol,4);
ShowTitle(myscreen,0);
NewWindow.Screen = myscreen;
if ((mywin = (struct Window *)OpenWindow(&NewWindow)) == 0)
cleanup(4);
SetMenuStrip(mywin, &mymenus);
rp = mywin->RPort;
/* Initialise communication ports for Console */
if ((ConReadPort = CreatePort(0,0)) == NULL)
cleanup(5);
if ((ConReadReq = CreateStdIO(ConReadPort)) == NULL)
cleanup(6);
ConReadReq->io_Data = (APTR)mywin;
ConReadReq->io_Length = sizeof(*mywin);
/* Open console and tell it to turn off the cursor */
if (OpenDevice("console.device",0,ConReadReq,0))
cleanup(7);
openconsole = 1;
/* Tell console to get first character ready for us */
QueueRead(ConReadReq,constring);
SetAPen(rp,2); /* Set primary colour */
SetBPen(rp,3); /* Set secondary colour */
clearscreen(); /* Fill screen to raster colour */
LoadRGB4(&(myscreen->ViewPort),screencol,4);
}
}
/*
* Outputs a character to the screen at co-ordinates x,y. If mode is 0,
* then output normal character, else output reverse character.
*
*/
void writechar(x,y,ch,mode)
int x,y;
char ch;
int mode;
{
char s[2];
s[0] = ch;
Move(rp,x * 8, y * 8 + 6); /* Quick multiply by 8 */
if (mode) {
SetDrMd(rp,INVERSVID|JAM2);
Text(rp,s,1);
SetDrMd(rp, JAM2);
} else
Text(rp,s,1);
}
/*
* Scrolls the screen up one line. Both the visible rastport screen,
* and the internal screen are scrolled.
*
*/
void scrollup()
{
register char *p, *q;
register int i;
ScrollRaster(rp,0,8,0,0,319,199);
for (p = (char *)screen,q = (char *)screen+40, i = 960; i--; *p++ = *q++)
;
for (i = 40; i--; *p++ = ' ')
;
cursory--;
}
/*
* Handles special characters like CR, cursor keys etc.
*
*/
void special(ch)
char ch;
{
register char *p, *q;
register int i,j;
switch (ch) {
case C_CR: /* Carriage Return */
cursorx = 0;
cursory++;
if (cursory >= 25)
scrollup();
break;
case C_UP: /* Cursor Up */
if (cursory)
cursory--;
break;
case C_DOWN: /* Cursor Down */
cursory++;
if (cursory >= 25)
scrollup();
break;
case C_LEFT: /* Cursor Left */
if (cursorx == 0) {
if (cursory) {
cursorx = 39;
cursory--;
}
} else
cursorx--;
break;
case C_RIGHT: /* Cursor Right */
cursorx++;
if (cursorx >= 40) {
cursorx = 0;
cursory++;
if (cursory >= 25)
scrollup();
}
break;
case C_DEL: /* Delete */
if (cursorx == 0) {
if (cursory) {
cursorx = 39;
cursory--;
screen[cursory][cursorx] = ' ';
writechar(cursorx,cursory,' ',0);
}
} else {
ScrollRaster(rp,8,0,cursorx*8,cursory*8,319,cursory*8+7);
/* Move chars from here to end of line back one space */
for (q = &(screen[cursory][cursorx]),
p = q - 1, i = 40 - cursorx;
i--;
*p++ = *q++)
;
*p = ' ';
cursorx--;
}
break;
case C_INSERT: /* Insert */
if (screen[cursory][39] == ' ' && cursorx < 39) {
ScrollRaster(rp,-8,0,cursorx*8,cursory*8,319,cursory*8+7);
for (p = &screen[cursory][39], q = p - 1, i = 39 - cursorx;
i--; *p-- = *q--)
;
*p = ' ';
}
break;
case C_CLEAR: /* Clear screen */
clearscreen();
break;
case C_HOME: /* Home cursor */
cursorx = 0;
cursory = 0;
break;
case C_REDRAW: /* Redraw entire screen */
for (i = 0; i < 25; i++)
for (j = 0; j < 40; j++)
writechar(j,i,screen[i][j],0);
break;
}
}
/*
* Outputs character to screen at current cursor position, and advances
* cursor to next position. Scrolls screen if necessary.
*
*/
void printchar(ch)
char ch;
{
if (ch < ' ')
special(ch);
else {
writechar(cursorx,cursory,ch,0);
screen[cursory][cursorx] = ch;
cursorx++;
if (cursorx >= 40) {
cursorx = 0;
cursory++;
if (cursory >= 25)
scrollup();
}
}
}
/*
* Outputs string to screen at current cursor position
*
*/
void printmess(s)
char *s;
{
while (*s)
printchar(*s++);
}