If you buy/have BlitzMax, this module will allow you to use normal 2D instead of the hardware accelerated stuff. It doesn't use Max2D so you'd have to do your own implementation of it -- I'm using this for software rendering. The code is licensed under the GNU Lesser General Public License (if you for some reason do not like the LGPL then you can jump off a bridge :D ).
ce_softdev.h
ce_softdev.c
softdevice.bmx (mod/cengine.mod/softdevice.mod/softdevice.bmx)
ce_softdev.h
// CEngine - 3D engine for graphics and game development // Copyright (C) 2005 Noel Raymond Cower // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // To contact the author, e-mail him at noel_cower@... and/or hooker.with.a.penis@... // Technically, this code has almost nothing to do with the software device // All it's used for is 2D functionality that is otherwise nonexistant in BlitzMax #ifndef _CE_SOFTDEV_H_ #define _CE_SOFTDEV_H_ // if i decide to not use SDL at some point in time, these bits might come in handy #include "SDL/SDL.h" #if SDL_BYTEORDER == SDL_BIG_ENDIAN # define CE_R_MASK 0xff000000 # define CE_G_MASK 0x00ff0000 # define CE_B_MASK 0x0000ff00 # define CE_A_MASK 0x000000ff #else # define CE_A_MASK 0xff000000 # define CE_R_MASK 0x00ff0000 # define CE_G_MASK 0x0000ff00 # define CE_B_MASK 0x000000ff #endif #ifndef NULL # ifdef _cplusplus # define NULL 0 # else # define NULL (void*)0 # endif #endif #ifdef _cplusplus extern "C" { #endif // For the sake of simplicity #define ce_New(i) ((i*)malloc(sizeof(i))) // And for the sake of consistency #define ce_Delete(i) (free(i)) // A buffer or surface typedef struct ce_Surface { SDL_Surface* surf; int locked; // Used for updating portions of the buffer int last_min_x, last_min_y; int last_max_x, last_max_y; int w; int h; } ce_Surface; extern ce_Surface* framebuffer; extern ce_Surface* curBuffer; // Used for updating portions of the framebuffer extern int last_min_x, last_min_y, last_max_x, last_max_y; // Initialize the software device int ce_InitDevice(int, int, int, int); // Dispose (free, delete, remove, destroy) the software device int ce_DisposeDevice(void); // Write a pixel to a buffer int ce_WritePixel(int, int, int, int, int, int, ce_Surface*); // Read a pixel from a buffer int ce_ReadPixel(int, int, ce_Surface*); // Get the framebuffer ce_Surface* ce_GetFramebuffer(void); // Creates a buffer ce_Surface* ce_CreateBuffer(int, int, int); // Disposes of a buffer int ce_DisposeBuffer(ce_Surface*); // Swaps the front and back buffers int ce_SwapBuffers(void); // Lock a buffer int ce_LockBuffer(ce_Surface*); // Unlock a buffer int ce_UnlockBuffer(ce_Surface*); // Get whether or not a buffer is locked int ce_BufferIsLocked(ce_Surface*); // Blits buffer src to buffer dst at X,Y int ce_BlitBuffer(ce_Surface*, ce_Surface*, int, int); // Fills a rectangular area of a buffer int ce_FillRect(ce_Surface*, int, int, int, int, int, int, int, int); // Sets a buffer to a single color int ce_ClearBuffer(ce_Surface*, int, int, int, int); #ifdef _cplusplus } #endif #endif //_CE_SOFTDEV_H_
ce_softdev.c
// CEngine - 3D engine for graphics and game development // Copyright (C) 2005 Noel Raymond Cower // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // To contact the author, e-mail him at noel_cower@... and/or hooker.with.a.penis@... // Technically, this code has almost nothing to do with the software device // All it's used for is 2D functionality that is otherwise nonexistant in BlitzMax #include "ce_softdev.h" #include "stdio.h" static ce_Surface* framebuffer = NULL; static ce_Surface* curBuffer = NULL; int ce_InitDevice(int w, int h, int bpp, int fs) { if (framebuffer!=NULL) return -2; // Cannot initialize it more than once int sdlFlags = SDL_SWSURFACE | SDL_DOUBLEBUF; if (fs>0) sdlFlags|=SDL_FULLSCREEN; SDL_Init(SDL_INIT_VIDEO); SDL_WM_SetCaption("CEngine Software Window", "CEngine Software Window"); SDL_Surface* surf = SDL_SetVideoMode(w,h,bpp,sdlFlags); if (surf==NULL) { fprintf(stderr, "Failed to create display device at %i*%i at %i BPP with %i for fullscreen, error is "%s"\n", w, h, bpp, fs, SDL_GetError()); return -1; } framebuffer = ce_New(ce_Surface); framebuffer->last_min_x = 0; framebuffer->last_min_y = 0; framebuffer->last_max_x = 0; framebuffer->last_max_y = 0; framebuffer->locked = 0; framebuffer->surf = surf; framebuffer->w = w; framebuffer->h = h; curBuffer = framebuffer; return 0; } int ce_DisposeDevice(void) { SDL_Quit(); framebuffer = NULL; curBuffer = NULL; } int ce_SwapBuffers(void) { if (framebuffer->locked > 0) return -1; //SDL_UpdateRect(framebuffer->surf,0,0,framebuffer->w,framebuffer->h); SDL_Flip(framebuffer->surf); return 0; } ce_Surface* ce_CreateBuffer(int w, int h, int bpp) { SDL_Surface* i = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, bpp, CE_R_MASK, CE_G_MASK, CE_B_MASK, CE_A_MASK); if (i == NULL) return NULL; ce_Surface* surf = ce_New(ce_Surface); surf->surf = i; surf->w = w; surf->h = h; surf->last_min_x = 0; surf->last_min_y = 0; surf->last_max_x = 0; surf->last_max_y = 0; surf->locked = 0; return surf; } ce_Surface* ce_GetFramebuffer(void) { return framebuffer; } int ce_DisposeBuffer(ce_Surface* surf) { SDL_FreeSurface(surf->surf); ce_Delete(surf); return 0; } int ce_WritePixel(int x, int y, int r, int g, int b, int a, ce_Surface* surf) { if (surf->locked==0) if (SDL_LockSurface(surf->surf)!=0) return -1; Uint32 pixel = SDL_MapRGBA(surf->surf->format,r,g,b,a); // Mostly just going off of the example in the SDL reference manual Uint8* bits = ((Uint8*)(surf->surf->pixels) + y*surf->surf->pitch + x*surf->surf->format->BytesPerPixel); switch (surf->surf->format->BytesPerPixel) { case 1: *((Uint8*)bits) = (Uint8)pixel; break; case 2: *((Uint16*)bits) = (Uint16)pixel; break; case 3: { Uint8 r,g,b; r=(pixel>>surf->surf->format->Rshift)&0xFF; g=(pixel>>surf->surf->format->Gshift)&0xFF; b=(pixel>>surf->surf->format->Bshift)&0xFF; *(bits + surf->surf->format->Rshift/8) = r; *(bits + surf->surf->format->Gshift/8) = g; *(bits + surf->surf->format->Bshift/8) = b; } break; case 4: *((Uint32*)bits) = (Uint32)pixel; break; } if (surf->locked==0) { SDL_UnlockSurface(surf->surf); // SDL_UpdateRect(surf->surf,x,y,1,1); } else { // set update region if (x < surf->last_min_x) surf->last_min_x = x; if (y < surf->last_min_y) surf->last_min_y = y; if (x > surf->last_max_x) surf->last_max_x = x; if (y > surf->last_max_y) surf->last_max_y = y; if (surf->last_max_y == surf->last_min_y) surf->last_max_y++; if (surf->last_max_x == surf->last_min_x) surf->last_max_x++; } } int ce_ReadPixel(int x, int y, ce_Surface* surf) { SDL_Surface* i = surf->surf; if (surf->locked == 0) if (SDL_LockSurface(i)!=0) return 0; Uint32 pix = *(Uint32*)((Uint8*)i->pixels + y*i->pitch + x*i->format->BytesPerPixel); //Uint32 pixel = pix; //Uint8 *colors = (Uint8*)pixel; //SDL_GetRGBA(pix, i->format, colors, colors+1, colors+2, colors+3); if (surf->locked == 0) SDL_UnlockSurface(i); return pix; } int ce_BufferIsLocked(ce_Surface* surf) { return (surf->locked>0); } int ce_LockBuffer(ce_Surface* surf) { int res = SDL_LockSurface(surf->surf); if (res == 0) surf->locked++; return res; } int ce_UnlockBuffer(ce_Surface* surf) { if (surf->locked == 0) return 0; SDL_UnlockSurface(surf->surf); surf->locked--; if (surf->locked==0) { SDL_Rect r; r.x = surf->last_min_x; r.y = surf->last_min_y; r.w = surf->last_max_x-surf->last_min_x; r.h = surf->last_max_y-surf->last_min_y; if (r.w == 0 || r.h == 0) return 0; if (r.x < 0) { r.w += r.x; r.x = 0; } if (r.y < 0) { r.h += r.y; r.y = 0; } // SDL_UpdateRect(surf->surf,r.x,r.y,r.w,r.h); } return 0; } int ce_FillRect(ce_Surface* surf, int x, int y, int w, int h, int r, int g, int b, int a) { SDL_Surface* i = surf->surf; SDL_Rect rc; if (x < 0) { w += x; x = 0; } if (y < 0) { h += y; y = 0; } rc.x = x; rc.y = y; rc.w = w; rc.h = h; if (rc.w == 0 || rc.h == 0) return 0; if (surf->locked==0) if (SDL_LockSurface(i)!=0) return -1; if (SDL_FillRect(i,&rc,SDL_MapRGBA(surf->surf->format,r,g,b,a))!=0) { if (surf->locked==0) SDL_UnlockSurface(i); return -1; } if (surf->locked==0) { SDL_UnlockSurface(i); // SDL_UpdateRect(i,x,y,w,h); } return 0; } int ce_ClearBuffer(ce_Surface* surf, int r, int g, int b, int a) { SDL_Surface* i = surf->surf; if (surf->locked==0) if (SDL_LockSurface(i)!=0) return -1; if (SDL_FillRect(i,NULL,SDL_MapRGBA(surf->surf->format,r,g,b,a))!=0) { if (surf->locked==0) SDL_UnlockSurface(i); return -1; } if (surf->locked==0) { SDL_UnlockSurface(i); // SDL_UpdateRect(i,0,0,surf->w,surf->h); } return 0; } int ce_BlitBuffer(ce_Surface* src, ce_Surface* dst, int x, int y) { SDL_Rect ra; SDL_Rect rb; ra.x = 0; ra.y = 0; ra.w = src->w; ra.h = src->h; rb.x = x; rb.y = y; rb.w = ra.w; rb.h = ra.h; return SDL_BlitSurface(src->surf,&ra,dst->surf,&rb); }
softdevice.bmx (mod/cengine.mod/softdevice.mod/softdevice.bmx)
'#Region Copyright and license ' CEngine - 3D engine for graphics and game development ' Copyright 2005 Noel R. Cower ' ' This library is free software; you can redistribute it and/or ' modify it under the terms of the GNU Lesser General Public ' License as published by the Free Software Foundation; either ' version 2.1 of the License, or (at your option) any later version. ' ' This library is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY; without even the implied warranty of ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ' Lesser General Public License for more details. ' ' You should have received a copy of the GNU Lesser General Public ' License along with this library; if not, write to the Free Software ' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ' ' To contact the author, e-mail him at noel_cower@... and/or hooker.with.a.penis@... '#End Region Strict Module CEngine.SoftDevice ModuleInfo "CEngine software device class" ModuleInfo "Uses SDL (www.libsdl.org VISIT THEM) for drawing" ModuleInfo "Written by Noel R. Cower" 'Import CEngine.EngineCore Import "-lSDL" Import "ce_softdev.c" Extern "C" Function ce_InitDevice(w:Int, h:Int, bpp:Int, fs:Int) Function ce_DisposeDevice() Function ce_CreateBuffer:Byte Ptr(w:Int,h:Int,bpp:Int) Function ce_DisposeBuffer(buffer:Byte Ptr) Function ce_GetFramebuffer:Byte Ptr() Function ce_ReadPixel(x:Int,y:Int,buf:Byte Ptr) Function ce_WritePixel(x:Int,y:Int,r:Int, g:Int, b:Int, a:Int,buf:Byte Ptr) Function ce_LockBuffer(buf:Byte Ptr) Function ce_UnlockBuffer(buf:Byte Ptr) Function ce_BufferIsLocked(buf:Byte Ptr) Function ce_SwapBuffers() Function ce_FillRect(surf:Byte Ptr, x:Int, y:Int, w:Int, h:Int, r:Int, g:Int, b:Int, a:Int) Function ce_ClearBuffer(surf:Byte Ptr, r:Int, g:Int, b:Int, a:Int) Function ce_BlitBuffer(src:Byte Ptr, dst:Byte Ptr, x:Int, y:Int) End Extern Type CSoftwareBuffer Global _framebuffer:CSoftwareBuffer Field _ptr:Byte Ptr Method GetWidth() Return (Int Ptr(_ptr+24))[0]; End Method Method GetHeight() Return (Int Ptr(_ptr+28))[0]; End Method Method Lock() ce_LockBuffer(_ptr) End Method Method Unlock() ce_UnlockBuffer(_ptr) End Method Method IsLocked() Return ce_BufferIsLocked(_ptr) End Method Method LockLevel() Return (Int Ptr(_ptr+4))[0] End Method Method WritePixel(x,y,r,g,b,a) Return ce_WritePixel(x,y,r,g,b,a,_ptr) End Method Method ReadPixel(x,y,r:Byte Ptr = Null,g:Byte Ptr = Null,b:Byte Ptr = Null,a:Byte Ptr = Null) Local ret = ce_ReadPixel(x,y,_ptr) If r <> Null Or g <> Null Or b <> Null Or a <> Null Local i:Byte Ptr = Byte Ptr(Varptr(ret)) If r <> Null Then r[0] = i[0] If g <> Null Then g[0] = i[1] If b <> Null Then b[0] = i[2] If a <> Null Then a[0] = i[3] EndIf Return ret End Method Method FillRect(x,y,w,h,r,g,b,a) Return ce_FillRect(_ptr,x,y,w,h,r,g,b,a) End Method Method Clear(r,g,b,a) Return ce_ClearBuffer(_ptr,r,g,b,a) End Method Method Blit(toSurf:CSoftwareBuffer,X:Int,Y:Int) Return ce_BlitBuffer(_ptr,toSurf._ptr,X,Y) End Method Method Delete() ce_DisposeBuffer(_ptr) _ptr = Null End Method Function Create:CSoftwareBuffer(Width:Int, Height:Int, BPP:Int=32) Local _ptr:Byte Ptr = ce_CreateBuffer(Width,Height,BPP) If _ptr = Null Then Return Null Local i:CSoftwareBuffer = New CSoftwareBuffer i._ptr = _ptr Return i End Function Function FrameBuffer:CSoftwareBuffer() If _framebuffer = Null And ce_GetFramebuffer() <> Null _framebuffer = New CSoftwareBuffer _framebuffer._ptr = ce_GetFramebuffer() EndIf Return _framebuffer End Function End Type