webForumDet fria alternativet

Projektarbetes problem

3 svar · 203 visningar · startad av msossna

msossnaMedlem sedan feb. 2002476 inlägg
#1

Jag håller på med projektarbete i skolan. Jag skriver just nu en funktion för att rita ut en bild i 8 bitars färger med upplösningen 640x480. Jag är relativt ny till directx (vilket jag använder), läser boken Spelprogrammering för Dummies. Koden kan vara delvis helt åt .... Kan någon berätta vad som är fel och hur jag enklast löser problemet

Jag använder Dev-C++
och bifogar källkoden (fast här med namnet .txt)

Marcus EMedlem sedan maj 20021 466 inlägg
#2

Du glömde att bifoga källkoden.

msossnaMedlem sedan feb. 2002476 inlägg
#3

Här är källkoden...

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <stdio.h>
#include <math.h>
#include <ddraw.h>
#include <io.h>
#define WINDOW_CLASS_NAME "WINCLASS1"
#define WINDOW_CLASS_NAME "WINCLASS1"

#define msHEIGHT 480
#define msWIDTH 640
#define msBPP 8
#define msTITLE "MY GAME"

#define BITMAPID 0x4D42

#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// container structure för .bmp filer
typedef struct BITMAP_FILE_TAG
    {
        BITMAPFILEHEADER bitmapfileheader; //bitmap file header
        BITMAPINFOHEADER bitmapinfoheader; //info (bla paletten)
        PALETTEENTRY palette[256]; //här sparars paletten
        UCHAR *buffer;  //pekare till data
    } BITMAP_FILE, *BITMAP_FILE_PTR;

//win/directx variabler
HWND main_window_handle = NULL;
LPDIRECTDRAW lpdd;
LPDIRECTDRAWSURFACE lpddsprimary;
LPDIRECTDRAWSURFACE lpwork;
LPDIRECTDRAWPALETTE lpddpal;
DDSURFACEDESC ddsd;
HRESULT hr;
PALETTEENTRY palette[256];
UCHAR *double_buffer = NULL, *primary_buffer = NULL;
BITMAP_FILE Bitmap8;

int dxInit(void *params = NULL);
int dxShutdown(void *params = NULL);
int dxMain(void *params = NULL);
int dxBild(int x, int y, char* filename, BITMAP_FILE_PTR bitmap);
int dxUnBild(BITMAP_FILE_PTR BildFil);
int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height);

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	PAINTSTRUCT ps;
    HDC hdc;

    switch(msg) //en switch för olika msg
    {
		case WM_CREATE: //när fönstret skapas
            return 0;
		break;

        case WM_PAINT: //när fönstret ska ritas om
            hdc = BeginPaint(hwnd, &ps); //startar omritning
            EndPaint(hwnd, &ps); //slutar omritning
            return 0;
		break;

        case WM_DESTROY: //när fönstret ska stängas
            PostQuitMessage(0); //skickar stängnings meddelande
            return 0;
		break;

        default: break; //default, gör inget
    } //switch(msg) end

    return (DefWindowProc(hwnd, msg, wparam, lparam));
} //WindowProc end

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcdmline, int ncmdshow)
{
    WNDCLASS winclass;
    HWND hwnd;
    MSG msg;

    winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc = WindowProc;
    winclass.cbClsExtra = 0;
    winclass.cbWndExtra = 0;
    winclass.hInstance = hinstance;
    winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
    winclass.lpszMenuName = NULL;
    winclass.lpszClassName = WINDOW_CLASS_NAME;

    if (!RegisterClass(&winclass))
        return 0;
    if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, msTITLE, WS_POPUP | WS_VISIBLE, 0, 0, msWIDTH, msHEIGHT, NULL, NULL, hinstance, NULL)))
        return(0);

    main_window_handle = hwnd;
    dxInit();

    while(1)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT) break;

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        dxMain();
    }
    dxShutdown();
    return (msg.wParam);
} //WinMain end

int dxMain(void *params = NULL)
{
  	if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE)) //om man trycker ner Esc eller space
        PostMessage(main_window_handle, WM_DESTROY, 0, 0); //posta ett avslutningsmeddelande

    memset(&ddsd,0,sizeof(ddsd)); 
    ddsd.dwSize = sizeof(ddsd);
    memset(double_buffer, 0, msHEIGHT * msWIDTH); //fixa minnet

    lpddsprimary->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
    primary_buffer = (UCHAR *)ddsd.lpSurface;
    primary_buffer = (UCHAR *)ddsd.lpSurface;
/*    for (int y=0; y < msHEIGHT; y++)
    {
        memcpy(&primary_buffer[y * ddsd.lPitch], &Bitmap8.buffer[y * msWIDTH], msWIDTH);
    } */

    //dxBild(0, 0, "test.bmp", &Bitmap8);
    lpddpal -> SetEntries(0, 0, 256, Bitmap8.palette); //ladda paletten till ddraw
    lpddsprimary -> Unlock(primary_buffer);
    Sleep(3); //vila lite
	return 1;
} //DxMain end

int dxShutdown(void *params = NULL)
{
    if (lpdd)
        lpdd -> Release(); //frigör lpdd
	if (lpddsprimary)
		lpddsprimary -> Release(); //frigör lpddsprimary
	if (lpwork)
		lpwork -> Release(); //frigör lpwork
	if (lpddpal)
		lpddpal -> Release(); //frigör lpddpal
	if (double_buffer)
		free(double_buffer); //frigör double_buffer
    dxUnBild(&Bitmap8);

    return 1;
} //dxShutdown end

int dxInit(void *params = NULL)
{
    if (DirectDrawCreate(NULL, &lpdd, NULL) != DD_OK) //skapa ddraw objekt
        return 0;
    //ställ in samverkansnivån
    if (lpdd -> SetCooperativeLevel(main_window_handle, DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT) != DD_OK)
        return 0;
    if ((lpdd -> SetDisplayMode(msWIDTH, msHEIGHT, msBPP)) != DD_OK) //ställ in skärmen (640x480x8)
        return 0;

	memset(&ddsd, 0, sizeof(ddsd)); //fixa minne
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS;
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
	if (lpdd -> CreateSurface(&ddsd, &lpddsprimary, NULL) != DD_OK) //skapa en yta
		return 0;

/*	memset(&ddsd, 0, sizeof(ddsd)); //fixa minne
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
	ddsd.dwHeight = msHEIGHT;
	ddsd.dwWidth = msWIDTH;
	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
	if (lpdd -> CreateSurface(&ddsd, &lpwork, NULL) != DD_OK) //skapa en sekundär yta
		return 0; */

    memset(palette,0,256*sizeof(PALETTEENTRY));
    for (int index=0; index<256; index++)
    {
        palette[index].peFlags = PC_NOCOLLAPSE;
    }
    if (lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,palette,&lpddpal,NULL)!=DD_OK)
        return(0);
    if (lpddsprimary->SetPalette(lpddpal)!=DD_OK)
        return(0);

	double_buffer = (UCHAR *)malloc(msHEIGHT * msWIDTH);
    dxBild(0, 0, "test.bmp", &Bitmap8);

    return 1;
} //dxInit end

int dxBild(int x, int y, char* FileName, BITMAP_FILE_PTR BildFil)
{
    int FileCheck;
    OFSTRUCT FilData; //fil data informationen

    if (!(FileCheck = OpenFile(FileName, &FilData, OF_READ)))
        return(0); //Om inte filen finns, return 0

    _lread(FileCheck, &BildFil -> bitmapfileheader, sizeof(BITMAPFILEHEADER)); //laddar bitmapheadern

    if (BildFil -> bitmapfileheader.bfType != BITMAPID) //om det inte är en bitmap
    {
    _lclose(FileCheck); //stäng filen
    return(0);
    }

    if (BildFil -> bitmapinfoheader.biBitCount == 8) //om palet info finns
    {
        _lread(FileCheck, &BildFil -> palette, 256 * sizeof(PALETTEENTRY));
        for (int i = 0; i < 256; i++)
        {
            //vänder på de gröna och röda fälten
            int TempColor = BildFil -> palette[i].peRed;
            BildFil -> palette[i].peBlue = TempColor;     
            BildFil -> palette[i].peFlags = PC_NOCOLLAPSE;
        }

    }

    _lseek(FileCheck, -(int)(BildFil -> bitmapinfoheader.biSizeImage), SEEK_END); //laddar bild datan
    if (!(BildFil -> buffer = (UCHAR *)malloc(BildFil -> bitmapinfoheader.biSizeImage))) //allokera minnet för bilden
    {
        _lclose(FileCheck); //stäng filen
        return(0);
    }

    _lread(FileCheck, BildFil -> buffer, BildFil -> bitmapinfoheader.biSizeImage); //läs in filen
    _lclose(FileCheck); //stäng filen

    return(1); //allt lyckades
} //dxBild end

int dxUnBild(BITMAP_FILE_PTR BildFil)
{
    if (BildFil -> buffer)
        {
            free(BildFil -> buffer); //frigör minnet
            BildFil -> buffer = NULL; //reset pekaren
        }

    return 1;
} //dxUnBil end
developerMedlem sedan aug. 2001458 inlägg
#4

Jag tror du förväntar dig lite mycket om du tror att någon ska berätta vilka fel du gör i ett kodstycke som du inte själv förstår. Mer realistiskt är nog att du kan få hjälp om hur man generellt för felsökning och bryter ner problem. Ett steg i taget...

Mitt förslag är att du läser lite mer i din bok så du har en förståelse för det du försöker göra, och inte har förväntingen att du blir en bra programmerare på 10 minuter. Jag har inte sett någon bli en bra programmerare på genvägar. Det kräver studier, enträgenhet och tid.

Har du läst igenom din egen kod och förstått steg för steg vad den gör? När du gjort detta och själv tror att koden är felfri är det lämpligt att stega igenom med en debugger och se att det du förväntar dig verkligen händer.

Kommentarer av typen "free(BildFil -> buffer); //frigör minnet" tillför inte särskilt mycket, snarare gör de koden oläsbar. Det är ganska uppenbar att free kommer frigöra minne. Försök kommentera logisk tankegång och sådant som inte är trivialt.

135 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
133 ms — hämta tråd, inlägg och bilagor (db)