graphics.cpp
author Mohammed Khoory
Wed Jul 07 19:11:38 2010 -0400 (22 months ago)
changeset 5 bcf3d6f89c62
parent 4 6366beccd211
permissions -rw-r--r--
Keyboard support, code movement, and TestManager

Major Changes
=============
- Added "testman.h" and "testman.cpp" to be used exclusively to test stuff (from a
GameManager perspective)
- Moved all the testing stuff to testman.cpp. 9game is just an empty class now to
manage other GameManagers
- Moved all the initializing stuff from 9Game to main. 9Game is like any other
GameManager now (just that it manages other GameManagers)
- Added keyboard.h and keyboard.c to handle keyboard interrupts (by replacing the
keyboard ISR)
- Keyboard is working :D can read more than one key at a time. (tested in
TestManager with WASD)

Minor Changes
=============
- Removed the exception throwing in SpriteLoader::unloadFile() (because it just
makes things unnecessarily complicated)
- added finished() to GameManager to indicate whether a GameManager is finished or
not
- Animation test + key control test. Sprite moves around depending on wasd key
input. (program ends when off screen to right)
- Set 0x00 as transparency color with drawSprite (TODO: change to make this
customizeable on runtime)
- Edited Makefile to reflect new changes

Notes
=====
- Animation seems to work nice and smooth in dosbox, slow in dosemu, so maybe I
should start testing in both dosemu and dosbox
- TODO: fix bug with drawSprite. When a sprite is drawn on the right of the screen
it "wraps around" to the other side by one pixel in width
     1 #include "graphics.h"
     2 
     3 GraphicsDevice::GraphicsDevice(void) 
     4 {
     5 //	init();
     6 	buffer = new unsigned char[64000]; 
     7 	if ( buffer )
     8 	{
     9 //		screen=(unsigned char *) MK_FP(0xa000, 0);
    10 		screen_width=320;
    11 		screen_height=200;
    12 		screen_size=64000u;
    13 //		enter_mode13h();
    14 		memset(buffer, 0, screen_size);
    15 	}
    16 	else
    17 	{
    18 		// no mem! Return error code!
    19 		printf("Out of mem!\n");
    20 //		throw bad_alloc();
    21 	}
    22 }
    23 
    24 GraphicsDevice::~GraphicsDevice()
    25 {
    26 	if(buffer != NULL)
    27 		delete[] buffer;	
    28 }
    29 
    30 void GraphicsDevice::enter_mode13h(void)
    31 {
    32 #if 0
    33 	union REGS in, out;
    34 
    35 	// get old video mode	
    36 	in.h.ah=0xf;
    37 	int86(0x10, &in, &out);
    38 //	old_mode=out.h.al;
    39 
    40 	// enter mode 13h
    41 	in.h.ah=0;
    42 	in.h.al=0x13;
    43 	int86(0x10, &in, &out);
    44 #endif
    45 
    46 	__dpmi_regs r;
    47 	
    48 	r.x.ax = 0x13;
    49 	__dpmi_int(0x10, &r);
    50 }
    51 
    52 
    53 
    54 void GraphicsDevice::leave_mode13h()
    55 {
    56 #if 0
    57 	union REGS in, out;
    58 
    59 	// change to the video mode we were in before we switched to mode 13h
    60 	in.h.ah=0;
    61 	in.h.al=3;
    62 	int86(0x10, &in, &out);
    63 	
    64 //	free(buffer);
    65 #endif
    66 	__dpmi_regs r;
    67 	r.x.ax = 3;
    68 	__dpmi_int(0x10, &r);
    69 }
    70 
    71 void GraphicsDevice::drawPixel(int x, int y, unsigned char color)
    72 {
    73 	if( x > screen_width || x < 0 || y > screen_height || y < 0 )
    74 		return;
    75 		
    76 	*(buffer + (y*screen_width) + x) = color;
    77 }
    78 
    79 //TODO fix bug when sprite is drawn on the right side of the screen
    80 void GraphicsDevice::drawSprite(int x, int y, struct sprite * aSprite)
    81 {
    82 	for(int i = 0; i< aSprite->height; i++)
    83 	{
    84 		for(int j = 0; j < aSprite->width; j++)
    85 		{
    86 			// if off-screen dont draw
    87 			if(!(x + j > screen_width || x + j < 0 || y + i > screen_height || y + i < 0)
    88 				&& !(*(aSprite->bitmap + (i*aSprite->width) + j) == 0))
    89 				*(buffer + ( (y+i) * screen_width) + (x+j)) = *(aSprite->bitmap + (i*aSprite->width) + j);
    90 		}
    91 	}
    92 }
    93 
    94 void GraphicsDevice::drawHorizontalLine(int x, int y, unsigned int length, unsigned char color)
    95 {
    96 
    97 	if( y < 0 || y > screen_height)
    98 		return;
    99 	
   100 	for(int i = 0; i < length; i++)
   101 	{
   102 		if( (x+ i) > screen_width)
   103 			break;
   104 		
   105 		*(buffer + (y * screen_width) + x + i) = color;
   106 	}
   107 }
   108 
   109 void GraphicsDevice::drawVerticalLine(int x, int y, unsigned int length, unsigned char color)
   110 {
   111 	if( x < 0 || x > screen_width)
   112 		return;
   113 	
   114 	for(int i = 0; i < length; i++)
   115 	{
   116 		if(y+i > screen_height)
   117 			break;
   118 		
   119 		*(buffer + ( (y+i) * screen_width) + x) = color;
   120 	}
   121 }
   122 
   123 void GraphicsDevice::drawLine(int x1, int y1, int x2, int y2, unsigned char color)
   124 {
   125 	
   126 }
   127 
   128 void GraphicsDevice::drawRectangle(int x1, int y1, int x2, int y2, unsigned char color)
   129 {
   130 	
   131 }
   132 
   133 void GraphicsDevice::drawString8x8(int x, int y, char * aString)
   134 {
   135 }
   136 
   137 void GraphicsDevice::drawString8x14(int x, int y, char * aString)
   138 {
   139 }
   140 
   141 // untested
   142 void GraphicsDevice::getPalette(char * palette)
   143 {
   144 	if(palette != NULL)
   145 	{
   146 		/* get the palette */
   147 		outportb(0x3c7, 0); /* want to read */
   148 		for (int i = 0; i < 768; i++)
   149 			palette[i] = inportb(0x3c9);
   150 	}
   151 }
   152 
   153 // untested 
   154 // number should be a multiple of 3 and max is 768 or else it doesnt do anything
   155 void GraphicsDevice::setPalette(char * palette, int number)
   156 {
   157 	if(number % 3 != 0 || number < 0 || number > 768 || palette == NULL)
   158 		return;
   159 	
   160 	// set palette
   161 	outportb(0x3c8, 0); 
   162 	for (int i = 0; i < number; i++)
   163 	{
   164 		outportb(0x3c9, palette[i] /4); // divide by 4 because color needs to be between 0-63
   165 	}
   166 }
   167 
   168  // with color black
   169 void GraphicsDevice::clearScreen()
   170 {
   171 	memset(buffer, 0, screen_size);
   172 }
   173 
   174 // with a defined color
   175 void GraphicsDevice::clearScreen(char color)
   176 {
   177 	memset(buffer, color, screen_size);
   178 }
   179 
   180 // draws the stuff on the screen
   181 void GraphicsDevice::updateBuffer()
   182 {
   183 	// wait for vertical re-trace
   184 	while ( inportb(INPUT_STATUS_0) & 8 )
   185 		;
   186 	while ( !(inportb(INPUT_STATUS_0) & 8) )
   187 		;
   188 
   189 	// copy everything to video memory
   190 	//_fmemcpy(screen, buffer, screen_size);
   191 	dosmemput(buffer, screen_size, SCREEN);
   192 }
   193 
   194 unsigned int GraphicsDevice::getScreenWidth(){ return screen_width; }
   195 unsigned int GraphicsDevice::getScreenHeight(){ return screen_height; }