25 March 2010, 06:45 | #1 |
Registered User
Join Date: Sep 2007
Location: Melbourne/Australia
Posts: 4,426
|
HAM8 C2P Hacking
Hiya,
I'm trying to use the HAM8 C2P routines written by the talented Mr Kalms. I've written a quick and nasty test application so I can do some benchmarks but it's not working. It doesn't crash or anything silly like that but it's not setting the screen to black (which is should), just a grey screen. Now I assume that it's because I'm not using the C2P correctly, either that or I should be setting a palette somewhere? Code:
// Standard includes. #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <assert.h> #include <ctype.h> // Amiga includes. #include <proto/exec.h> #include <proto/graphics.h> #include <proto/intuition.h> #include <proto/asl.h> #include <exec/memory.h> #include <exec/types.h> #include <graphics/gfxbase.h> #include <clib/exec_protos.h> #include <clib/alib_protos.h> #include <clib/lowlevel_protos.h> #include <clib/timer_protos.h> #include <clib/dos_protos.h> #include <clib/icon_protos.h> #include "c2p_stub.h" bool quit = false; int SCREENWIDTH = 320; int SCREENHEIGHT = 240; static struct Screen *video_screen = NULL; static struct Window *video_window = NULL; static struct BitMap video_bitmap[2] = { {0, 0, 0, 0, 0, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}}, {0, 0, 0, 0, 0, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}} }; static PLANEPTR video_raster[2] = {NULL, NULL}; /* contiguous bitplanes */ static struct ScreenBuffer *video_sb[2] = {NULL, NULL}; static int video_which = 0; static int video_depth = 0; static int chunkyBufferSize = 0; static UWORD emptypointer[] = { 0x0000, 0x0000, /* reserved, must be NULL */ 0x0000, 0x0000, /* 1 row of image data */ 0x0000, 0x0000 /* reserved, must be NULL */ }; static UBYTE *chunkyBuffer = NULL; void error(const char *s, ...) { char errorString[1024]; char logMessage[1024]; va_list va; va_start(va, s); vsprintf((char *)errorString, (const char *)s, (char *)va); va_end(va); sprintf(logMessage, "Error: %s!\n", errorString); printf(logMessage); exit(1); } void debug(int level, const char *s, ...) { char buf[1024]; va_list va; if (level > 100) return; va_start(va,s); vsprintf((char *)buf, (const char *)s, (char *)va); va_end(va); printf("Debug: %s.\n", buf); fflush(stdout); } void I_InitGraphics() { ULONG propertymask, idcmp, wflags, pixfmt; struct Rectangle rect; int mode, depth, nbytes, p; DisplayInfoHandle handle; struct DisplayInfo dispinfo; struct DimensionInfo dimsinfo; static struct TextAttr topaz8 = {"topaz.font", 8, FS_NORMAL, FPF_ROMFONT}; mode = BestModeID(BIDTAG_NominalWidth, SCREENWIDTH, BIDTAG_NominalHeight, SCREENHEIGHT, BIDTAG_DesiredWidth, SCREENWIDTH, BIDTAG_DesiredHeight, SCREENHEIGHT, BIDTAG_MonitorID, VGA_MONITOR_ID, BIDTAG_DIPFMustHave, DIPF_IS_HAM | DIPF_IS_AA, TAG_END); if(mode == INVALID_ID) { error("Could not find a valid mode!"); } if ((handle = FindDisplayInfo (mode)) == NULL) { error ("Can't FindDisplayInfo() for mode %08x", mode); } if ((nbytes = GetDisplayInfoData (handle, (UBYTE *)&dispinfo, sizeof(struct DisplayInfo), DTAG_DISP, NULL)) < 40 ) { error ("Can't GetDisplayInfoData() for mode %08x, got %d bytes", mode, nbytes); } if ((nbytes = GetDisplayInfoData (handle, (UBYTE *)&dimsinfo, sizeof(dimsinfo), DTAG_DIMS, NULL)) < 66) { error ("Can't GetDisplayInfoData() for mode %08x, got %d bytes", mode, nbytes); } SCREENWIDTH = dimsinfo.Nominal.MaxX - dimsinfo.Nominal.MinX + 1; SCREENHEIGHT = dimsinfo.Nominal.MaxY - dimsinfo.Nominal.MinY + 1; debug(1, "Red bits = %d" , dispinfo.RedBits); debug(1, "Green bits = %d" , dispinfo.GreenBits); debug(1, "Blue bits = %d" , dispinfo.BlueBits); debug(1, "PaletteRange = %d" , dispinfo.PaletteRange); debug(1, "Width = %d" , SCREENWIDTH); debug(1, "Height = %d" , SCREENHEIGHT); debug(1, "MaxDepth = %d" , dimsinfo.MaxDepth); video_depth = dimsinfo.MaxDepth; rect.MinX = 0; rect.MinY = 0; rect.MaxX = SCREENWIDTH - 1; rect.MaxY = SCREENHEIGHT - 1; for (int i = 0; i < 2; i++) { if ((video_raster[i] = (PLANEPTR)AllocRaster (SCREENWIDTH, video_depth * SCREENHEIGHT)) == NULL) { error ("AllocRaster() failed"); } memset (video_raster[i], 0, video_depth * RASSIZE (SCREENWIDTH, SCREENHEIGHT)); InitBitMap (&video_bitmap[i], video_depth, SCREENWIDTH, SCREENHEIGHT); for (depth = 0; depth < video_depth; depth++) { video_bitmap[i].Planes[depth] = video_raster[i] + depth * RASSIZE (SCREENWIDTH, SCREENHEIGHT); } } if ((video_screen = OpenScreenTags (NULL, SA_Type, CUSTOMSCREEN | CUSTOMBITMAP, SA_DisplayID, mode, SA_DClip, (ULONG)&rect, SA_Width, SCREENWIDTH, SA_Height, SCREENHEIGHT, SA_Depth, video_depth, SA_Font, (ULONG)&topaz8, SA_Quiet, TRUE, SA_BitMap, (ULONG)&video_bitmap[0], // custom bitmap, contiguous planes TAG_DONE, 0)) == NULL) { error ("OpenScreen() failed"); } idcmp = IDCMP_RAWKEY|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW; wflags = WFLG_ACTIVATE | WFLG_BORDERLESS | WFLG_RMBTRAP | WFLG_NOCAREREFRESH | WFLG_SIMPLE_REFRESH; if ((video_window = OpenWindowTags (NULL, WA_Left, 0, WA_Top, 0, WA_Width, SCREENWIDTH, WA_Height, SCREENHEIGHT, WA_IDCMP, idcmp, WA_Flags, wflags, WA_CustomScreen, (ULONG)video_screen, TAG_DONE)) == NULL) { error ("OpenWindow() failed"); } SetPointer (video_window, emptypointer, 1, 16, 0, 0); chunkyBufferSize = (SCREENWIDTH * SCREENHEIGHT * 16); // set back buffer to black. chunkyBuffer = (UBYTE*)AllocMem(chunkyBufferSize, MEMF_FAST | MEMF_CLEAR); // Init C2P. c2p_2rgb565_4rgb555h8_040_init_stub(SCREENWIDTH, SCREENHEIGHT, 0, 0, SCREENWIDTH / 8, (SCREENWIDTH * SCREENHEIGHT) / 8, (SCREENWIDTH * 16) / 8); } void I_ShutdownGraphics () { if (video_window != NULL) { ClearPointer (video_window); CloseWindow (video_window); video_window = NULL; } if (video_screen != NULL) { CloseScreen (video_screen); video_screen = NULL; } for (int i = 0; i < 2; i++) { if (video_raster[i] != NULL) { FreeRaster (video_raster[i], SCREENWIDTH, video_depth * SCREENHEIGHT); video_raster[i] = NULL; } } if (chunkyBuffer) { FreeMem(chunkyBuffer, chunkyBufferSize); } } void handleInput() { struct IntuiMessage *msg; int key = 0; while (msg = (struct IntuiMessage *)GetMsg(video_window->UserPort)) { ReplyMsg((struct Message *)msg); switch (msg->Class) { case IDCMP_RAWKEY: quit = true; break; } } } void updateScreen() { c2p_2rgb565_4rgb555h8_040_stub(chunkyBuffer, video_raster[video_which]); } int main(int argc, char* argv[]) { I_InitGraphics(); updateScreen(); do { handleInput(); } while(!quit); I_ShutdownGraphics(); } Last edited by NovaCoder; 25 March 2010 at 23:55. |
25 March 2010, 06:51 | #2 |
Registered User
Join Date: Sep 2007
Location: Melbourne/Australia
Posts: 4,426
|
Or maybe I stuffed up the assembly stub?
Code:
extern "C" void c2p_2rgb565_4rgb555h8_040_init_stub(UWORD chunkyx, UWORD chunkyy, UWORD scroffsx, UWORD scroffsy, ULONG rowlen, ULONG bplsize, ULONG chunkylen) { register UWORD _chunkyx __asm("d0") = _chunkyx; register UWORD _chunkyy __asm("d1") = _chunkyy; register UWORD _scroffsx __asm("d2") = _scroffsx; register UWORD _scroffsy __asm("d3") = _scroffsy; register ULONG _rowlen __asm("d4") = _rowlen; register ULONG _bplsize __asm("d5") = _bplsize; register ULONG _chunkylen __asm("d6") = chunkylen; __asm volatile ( "jsr _c2p_2rgb565_4rgb555h8_040_init" : : "r" (_chunkyx), "r" (_chunkyy), "r" (_scroffsx), "r" (_scroffsy), "r" (_rowlen), "r" (_bplsize), "r" (_chunkylen) : "cc", "memory"); } extern "C" void c2p_2rgb565_4rgb555h8_040_stub(UBYTE *chunkybuffer, UBYTE *bitplanes) { register UBYTE * _chunkybuffer __asm("a0") = chunkybuffer; register UBYTE * _bitplanes __asm("a1") = bitplanes; __asm volatile ( "jsr _c2p_2rgb565_4rgb555h8_040" : : "r" (_chunkybuffer), "r" (_bitplanes) : "cc", "memory"); } |
25 March 2010, 10:37 | #3 |
Registered User
Join Date: Sep 2007
Location: Melbourne/Australia
Posts: 4,426
|
Or maybe this doesn't give you a HAM8 screen mode?
Code:
mode = BestModeID(BIDTAG_NominalWidth, SCREENWIDTH, BIDTAG_NominalHeight, SCREENHEIGHT, BIDTAG_DesiredWidth, SCREENWIDTH, BIDTAG_DesiredHeight, SCREENHEIGHT, BIDTAG_MonitorID, VGA_MONITOR_ID, BIDTAG_DIPFMustHave, DIPF_IS_HAM | DIPF_IS_AA, TAG_END); |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
C2P Assember update required (6bit EHB hacking!) | NovaCoder | Coders. General | 14 | 16 April 2011 12:26 |
HAM8 screen question. | Thorham | Coders. General | 28 | 04 April 2011 19:26 |
Problem making ham8 icons. | Thorham | support.Apps | 0 | 12 March 2008 22:30 |
fast HAM8 conversion ? | meynaf | Coders. General | 237 | 23 February 2008 08:58 |
Multiple HAM8 pictures? | killergorilla | support.Other | 4 | 15 February 2007 14:41 |
|
|