Mercurial > repos > rhope
view visuality.c @ 75:0083b2f7b3c7
Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 06 Jul 2010 07:52:59 -0400 |
parents | 76568becd6d6 |
children |
line wrap: on
line source
#include <stdio.h> #include <math.h> #include "structs.h" #include "visuality.h" #include "interp.h" #include "parser.h" #include "saveload.h" #define NUM_SPRITES 5 FILE * outfile; HGLRC hRC = NULL; HDC hDC = NULL; HWND hWnd = NULL; HINSTANCE hInstance; GLuint glyph_base; BOOL mouse_left_down=FALSE; BOOL mouse_leftstart_down=FALSE; int mouse_lastx; int mouse_lasty; int mouse_curx; int mouse_cury; int start_wire_worker=-1; int start_wire_ionum=-2; BOOL start_wire_isinput; BOOL checked_mouse_pos=FALSE; char new_name_buf[256]; int buf_size=0; extern char text_buf[256]; extern int text_buf_size=0; extern BOOL execute_active; worker * view_workerlist; wire * view_wirelist; int current_def=0; /* void save_program(char * filename) { worker * aworkerlist; wire * awirelist; FILE * savefile; int def_num, version = 1; savefile = fopen(filename, "wb"); if(!savefile) return; deflist[current_def].num_workers = num_workers; deflist[current_def].num_wires = num_wires; fwrite(&version, 4, 1, savefile); fwrite(&num_defs, 4, 1, savefile); fwrite(deflist, sizeof(worker_def), num_defs, savefile); for(def_num = 0; def_num < num_defs; ++def_num) { if(deflist[def_num].workerlist) { fwrite(&def_num, 4, 1, savefile); //fwrite(&(deflist[def_num].num_workers), 4, 1, savefile); fwrite(deflist[def_num].workerlist, sizeof(worker), deflist[def_num].num_workers, savefile); //fwrite(&(deflist[def_num].num_wires), 4, 1, savefile); fwrite(deflist[def_num].wirelist, sizeof(wire), deflist[def_num].num_wires, savefile); } } def_num = -1; fwrite(&def_num, 4, 1, savefile); fclose(savefile); } void load_program(char * filename) { char msg[256]; worker * aworkerlist; wire * awirelist; FILE * loadfile; int def_num, version; loadfile = fopen(filename, "rb"); if(!loadfile) { MessageBox(NULL, "Could not open file","Error",MB_OK); return; } fread(&version, 4, 1, loadfile); if(version != 1) { MessageBox(NULL, "Can't read files of this version.","Error",MB_OK); return; } fread(&num_defs, 4, 1, loadfile); fread(deflist, sizeof(worker_def), num_defs, loadfile); fread(&def_num, 4, 1, loadfile); while(def_num >= 0 && !feof(loadfile)) { sprintf(msg, "Reading def %X at %X", def_num, ftell(loadfile)); MessageBox(NULL, msg, "debug",MB_OK); deflist[def_num].workerlist = malloc((deflist[def_num].num_workers+512)*sizeof(worker)); fread(deflist[def_num].workerlist, sizeof(worker), deflist[def_num].num_workers, loadfile); deflist[def_num].wirelist = malloc((deflist[def_num].num_wires+1024)*sizeof(wire)); fread(deflist[def_num].wirelist, sizeof(wire), deflist[def_num].num_wires, loadfile); deflist[def_num].workers_to_wires_up = malloc((deflist[def_num].num_wires+1024)*sizeof(int)); deflist[def_num].workers_to_wires_down = malloc((deflist[def_num].num_wires+1024)*sizeof(int)); fread(&def_num, 4, 1, loadfile); } fclose(loadfile); view_workerlist = deflist[0].workerlist; view_wirelist = deflist[0].wirelist; num_workers = deflist[0].num_workers; num_wires = deflist[0].num_wires; initpredefworkers(); //sprintf(msg,"%d workers, %d wires in %s",deflist[0].num_workers,deflist[0].num_wires,deflist[0].name); //MessageBox(NULL,msg,"visdbg",MB_OK); }*/ BOOL keys[256]; BOOL active = TRUE; BOOL fullscreen=TRUE; BOOL gameover = FALSE; GLfloat xrot; // X Rotation ( NEW ) GLfloat yrot; // Y Rotation ( NEW ) GLfloat zrot; // Z Rotation ( NEW ) GLuint texture[NUM_SPRITES]; // Storage For One Texture ( NEW ) float xsizes[NUM_SPRITES] = {0.75f, 1.0f, 0.25f, 0.25f, 2.0f}; float ysizes[NUM_SPRITES] = {1.0f, 0.5f, 0.25f, 0.25f, 2.0f}; float xtexturefit[NUM_SPRITES] = {0.75f, 1.0f, 1.0f, 1.0f, 1.0f}; float ytexturefit[NUM_SPRITES] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f}; float gunxpos = 5.0f; char spritenames[NUM_SPRITES][32] = {"rini.bmp", "zapper.bmp", "heart.bmp", "fireball.bmp", "kiss.bmp"}; #define SCREEN_WIDTH_REL 8.8f #define SCREEN_HEIGHT_REL 6.6f #define PI 3.14159265 int selected_worker = -1; int selected_wire = -1; int killed = 0; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image { FILE *File=NULL; // File Handle if (!Filename) // Make Sure A Filename Was Given { return NULL; // If Not Return NULL } File=fopen(Filename,"r"); // Check To See If The File Exists if (File) // Does The File Exist? { fclose(File); // Close The Handle return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer } return NULL; // If Load Failed Return NULL } /* int LoadGLTextures() // Load Bitmaps And Convert To Textures { int Status=FALSE; // Status Indicator AUX_RGBImageRec *TextureImage[NUM_SPRITES]; // Create Storage Space For The Texture int i; for(i = 0; i < NUM_SPRITES; ++i) { TextureImage[i] = NULL; // Set The Pointer To NULL // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit if (TextureImage[i]=LoadBMP(spritenames[i])) { Status=TRUE; // Set The Status To TRUE glGenTextures(1, &texture[i]); // Create The Texture // Typical Texture Generation Using Data From The Bitmap glBindTexture(GL_TEXTURE_2D, texture[i]); // Generate The Texture glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[i]->data); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering } if (TextureImage[i]) // If Texture Exists { if (TextureImage[i]->data) // If Texture Image Exists { free(TextureImage[i]->data); // Free The Texture Image Memory } free(TextureImage[i]); // Free The Image Structure } //xsizes[i] = 0.5f; //ysizes[i] = 1.0f; } return Status; // Return The Status } */ GLvoid ReSizeGLScene(GLsizei width, GLsizei height) { if(height ==0) height = 1; glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); //Reset projection matrix glLoadIdentity(); //Calculate aspect ratio gluPerspective(45.0f, (GLfloat)width/ (GLfloat)height, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //reset modelview matrix } int InitGL(GLvoid) { //if (!LoadGLTextures()) // Jump To Texture Loading Routine ( NEW ) //{ // return FALSE; // If Texture Didn't Load Return FALSE ( NEW ) //} HFONT font; glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //blackness glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glEnable(GL_COLOR_MATERIAL); font = CreateFont(-24, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_SWISS || VARIABLE_PITCH, "Arial"); SelectObject(hDC, font); glyph_base = glGenLists(224); wglUseFontOutlines(hDC, 32, 224, glyph_base, 0.0, 0.0, WGL_FONT_POLYGONS, NULL); DeleteObject(font); return TRUE; } void drawtriangle(double xpos, double ypos, double width, double height, double angle) { if(xpos != 0.0 || ypos != 0.0) glTranslatef(xpos, ypos, 0.0); if(angle != 0.0) glRotatef(angle, 0.0,0.0,1.0); glBegin(GL_TRIANGLES); glVertex2f(0.0, height/2); //Top glVertex2f(0.0 - width/2, 0.0 - height/2); //Left glVertex2f(width/2, 0.0 - height/2); //Right glEnd(); if(angle != 0.0) glRotatef(0.0-angle, 0.0,0.0,1.0);//restore rotation without loading identity if(xpos != 0.0 || ypos != 0.0) glTranslatef(0.0-xpos, 0.0-ypos, 0.0); } void drawrect(double xpos, double ypos, double width, double height, double angle) { if(xpos != 0.0 || ypos != 0.0) glTranslatef(xpos, ypos, 0.0); if(angle != 0.0) glRotatef(angle, 0.0,0.0,1.0); glBegin(GL_QUADS); glVertex2f(0.0 - width/2, height/2.0); //Top Left glVertex2f(width/2, height/2.0); //Top Right glVertex2f(width/2, 0.0 - height/2.0); //Bottom Right glVertex2f(0.0 - width/2, 0.0 - height/2.0); //Bottom Left glEnd(); if(angle != 0.0) glRotatef(0.0-angle, 0.0,0.0,1.0);//restore rotation without loading identity if(xpos != 0.0 || ypos != 0.0) glTranslatef(0.0-xpos, 0.0-ypos, 0.0); } void drawshapestrip(int shape_type, double length, double ypos, double width, double height, int num) { double currentpos, spacing; int i; spacing = length/(double)num; currentpos = 0.0 - length/2.0 + spacing/2.0; for(i = 0; i < num; ++i) { if(shape_type == 0) drawtriangle(currentpos, ypos, width, height, 0.0); else drawrect(currentpos, ypos, width, height, 0.0); currentpos += spacing; } } double get_io_xpos(worker * some_worker, int output_num, BOOL is_input) { double length, currentpos, spacing; if(is_input && output_num == -1) return some_worker->xpos + some_worker->width/2.0 + INPUT_SIZE/2.0; if(some_worker->type == 2 && is_input) //Trapezoid length = 2.0*(some_worker->width)/3.0; else length = some_worker->width; fprintf(outfile, "Worker length: %f, worker width: %f\n"); if(is_input) spacing = length/(some_worker->num_inputs); else spacing = length/(some_worker->num_outputs); currentpos = some_worker->xpos - length/2.0 + spacing/2.0; return currentpos + spacing * (double)output_num; } double get_io_ypos(worker * some_worker, int output_num, BOOL is_input) { if(is_input && output_num != -1) return some_worker->ypos + (some_worker->height)/2.0; else return some_worker->ypos - ((some_worker->height)/2.0); } void drawshape(int shape_type, double xpos, double ypos, double width, double height, double angle, int inputs, int outputs, char *text, BOOL selected) { double x, y,temp, currentpos, spacing; double *inputx, *inputy, *outputx, *outputy; double ioangle, hypot; int i; glLoadIdentity(); glTranslatef(SCREEN_WIDTH_REL / (-2.0f) + xpos, SCREEN_HEIGHT_REL / (-2.0f) + ypos,-8.0f); xpos = 0.0; ypos = 0.0; glRotatef(angle, 0.0,0.0,1.0); if(selected) glColor3f(SELECT_RED, SELECT_GREEN, SELECT_BLUE); else glColor3f(BODY_RED, BODY_GREEN, BODY_BLUE); switch(shape_type) { case 0: //Triangle drawtriangle(0.0, 0.0, width, height, 0.0); glTranslatef(0.0-width/4.0, 0.0-height/4.0,0); break; case 1: //Rectangle drawrect(0.0, 0.0, width, height, angle); glColor3f(INPUT_RED, INPUT_GREEN, INPUT_BLUE); if(inputs) drawshapestrip(0, width, height/2.0 + INPUT_SIZE/2.0,INPUT_SIZE, INPUT_SIZE, inputs); drawtriangle(xpos + width/2.0 + INPUT_SIZE/2.0, ypos-height/2.0+INPUT_SIZE/2.0, INPUT_SIZE, INPUT_SIZE, 0.0); glColor3f(OUTPUT_RED, OUTPUT_GREEN, OUTPUT_BLUE); if(outputs) drawshapestrip(1, width, 0.0-(height/2.0 + OUTPUT_SIZE/2.0),OUTPUT_SIZE, OUTPUT_SIZE, outputs); glTranslatef(0.0-width/2.0 + width/16.0, 0.0-height/3.0, 0.0); break; case 2: //Trapezoid glBegin(GL_QUADS); glVertex2f(xpos - width/3.0 , ypos + height/2.0); //Top Left glVertex2f(xpos + width/3.0, ypos + height/2.0); //Top Right glVertex2f(xpos + width/2.0, ypos - height/2.0); //Bottom Right glVertex2f(xpos - width/2.0, ypos - height/2.0); //Bottom Left glEnd(); glColor3f(INPUT_RED, INPUT_GREEN, INPUT_BLUE); if(inputs) drawshapestrip(0, 2.0*(width/3.0), height/2.0 + INPUT_SIZE/2.0,INPUT_SIZE, INPUT_SIZE, inputs); drawtriangle(xpos + width/2.0 + INPUT_SIZE/2.0, ypos-height/2.0+INPUT_SIZE/2.0, INPUT_SIZE, INPUT_SIZE, 0.0); glColor3f(OUTPUT_RED, OUTPUT_GREEN, OUTPUT_BLUE); if(outputs) drawshapestrip(1, width, 0.0-(height/2.0 + OUTPUT_SIZE/2.0),OUTPUT_SIZE, OUTPUT_SIZE, outputs); glTranslatef(0.0-width/3.0, 0.0-height/3.0, 0.0); break; case 3: //Ellipse x = 3.4587; y = 2293.784; glBegin(GL_TRIANGLE_FAN); glVertex2f(0.0, 0.0); if(inputs) { spacing = width/(double)inputs; currentpos = 0.0-width/2.0 + spacing/2.0; inputx = (double *)malloc(inputs*sizeof(double)); inputy = (double *)malloc(inputs*sizeof(double)); i = 0; } for(x = 0.0-width/2 ; x <= width/2.0+CIRCLE_STEP; x += CIRCLE_STEP) { y = sqrt(fabs(pow(height/2.0,2) - (pow(height/2.0,2)*pow(x, 2))/pow(width/2.0, 2))); glVertex2f(x, y); if(inputs && x >= currentpos) { inputx[i] = x; inputy[i] = y; ++i; currentpos += spacing; } } x -= CIRCLE_STEP; while(x >= 0.0-width/2) { y = 0.0-sqrt(fabs(pow(height/2.0,2) - (pow(height/2.0,2)*pow(x, 2))/pow(width/2.0, 2))); glVertex2f(x+xpos, y+ypos); x -= CIRCLE_STEP; } glEnd(); glColor3f(INPUT_RED, INPUT_GREEN, INPUT_BLUE); for(i = 0; i < inputs; ++i) { ioangle = atan2(inputy[i], inputx[i]); hypot = sqrt(pow(inputx[i],2) + pow(inputy[i], 2)) + INPUT_SIZE/2; x = hypot * cos(ioangle); y = hypot * sin(ioangle); ioangle *= (180/PI); fprintf(outfile, "oldx: %f, oldy: %f, newx: %f, newy %f, hypot %f, angle %f\n",inputx[i],inputy[i],x,y,hypot, ioangle); drawtriangle(x,y,INPUT_SIZE,INPUT_SIZE, 90-ioangle); } glTranslatef(0.0-width/8.0, 0.0, 0.0); break; default: break; } if(text) { glColor3f(TEXT_RED, TEXT_GREEN, TEXT_BLUE); glPushAttrib(GL_LIST_BIT); glListBase(glyph_base-32); glScalef(0.25,0.25,0.25); glCallLists(strlen(text),GL_UNSIGNED_BYTE, text); glPopAttrib(); } } #define INTX_TO_FLOAT_REL(val) (((double)val)*SCREEN_WIDTH_REL/640.0) #define INTY_TO_FLOAT_REL(val) (((double)val)*SCREEN_HEIGHT_REL/480.0) //void drawshape(int shape_type, double xpos, double ypos, double width, double height, double angle, int inputs, int outputs) int DrawGLScene(GLvoid) { double line_startx; double line_starty; double line_endx; double line_endy; double m,b,x,y,mousey; int i,j; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); for(i = 0; i < num_workers; ++i) { if(mouse_leftstart_down && INTX_TO_FLOAT_REL(mouse_curx) > (view_workerlist[i].xpos - view_workerlist[i].width/2.0) && INTX_TO_FLOAT_REL(mouse_curx) < (view_workerlist[i].xpos + view_workerlist[i].width/2.0) && INTY_TO_FLOAT_REL(mouse_cury) > (view_workerlist[i].ypos - view_workerlist[i].height/2.0) && INTY_TO_FLOAT_REL(mouse_cury) < (view_workerlist[i].ypos + view_workerlist[i].height/2.0)) { view_workerlist[i].grabbed = TRUE; selected_worker = i; selected_wire = -1; mouse_leftstart_down = FALSE; } else if(mouse_leftstart_down && INTX_TO_FLOAT_REL(mouse_curx) > (view_workerlist[i].xpos - view_workerlist[i].width/2.0) //Check for mouse in input or output area && INTX_TO_FLOAT_REL(mouse_curx) < (view_workerlist[i].xpos + view_workerlist[i].width/2.0) && (INTY_TO_FLOAT_REL(mouse_cury) > (view_workerlist[i].ypos - view_workerlist[i].height/2.0 - OUTPUT_SIZE)) && (INTY_TO_FLOAT_REL(mouse_cury) < (view_workerlist[i].ypos + view_workerlist[i].height/2.0 + INPUT_SIZE))) { if(INTY_TO_FLOAT_REL(mouse_cury) > view_workerlist[i].ypos && view_workerlist[i].num_inputs > 0)//is mouse above or below worker (inputs are above, outputs below)? { fputs("Hit on input region.\n", outfile); for(j = 0; j < view_workerlist[i].num_inputs; ++j) { if(INTX_TO_FLOAT_REL(mouse_curx) > (get_io_xpos(&view_workerlist[i], j, TRUE)-INPUT_SIZE/2.0) && INTX_TO_FLOAT_REL(mouse_curx) < (get_io_xpos(&view_workerlist[i], j, TRUE)+INPUT_SIZE/2.0)) { fprintf(outfile, "Hit on input number %d on worker %d.\n", j, i); mouse_leftstart_down = FALSE; if(start_wire_worker >= 0) { fprintf(outfile, "Adding wire %d. output_num: %d, input_num: %d", num_wires,start_wire_ionum, j); //Add wire view_wirelist[num_wires].start_worker = start_wire_worker; view_wirelist[num_wires].end_worker = i; view_wirelist[num_wires].output_num = start_wire_ionum;; view_wirelist[num_wires].input_num = j; ++num_wires; start_wire_worker = start_wire_ionum = -1; } else { fputs("Saving information for later wire creation.\n", outfile); start_wire_worker = i; start_wire_ionum = j; start_wire_isinput=TRUE; } break; } } } else if(view_workerlist[i].num_outputs > 0) { fputs("Hit on output region.\n", outfile); for(j = 0; j < view_workerlist[i].num_outputs; ++j) { fprintf(outfile, "Checking mouse x(%f) for hit on output number %d with position %f\n", INTX_TO_FLOAT_REL(mouse_curx), j, get_io_xpos(&view_workerlist[i], j, FALSE)); if(INTX_TO_FLOAT_REL(mouse_curx) > (get_io_xpos(&view_workerlist[i], j, FALSE)-OUTPUT_SIZE/2.0) && INTX_TO_FLOAT_REL(mouse_curx) < (get_io_xpos(&view_workerlist[i], j, FALSE)+OUTPUT_SIZE/2.0)) { fprintf(outfile, "Hit on output number %d on worker %d.\n", j, i); mouse_leftstart_down = FALSE; if(start_wire_worker >= 0) { fprintf(outfile, "Adding wire %d. output_num: %d, input_num: %d", num_wires, j, start_wire_ionum); //Add wire view_wirelist[num_wires].start_worker = i; view_wirelist[num_wires].end_worker = start_wire_worker; view_wirelist[num_wires].output_num = j; view_wirelist[num_wires].input_num = start_wire_ionum; if(start_wire_ionum == -1) view_workerlist[start_wire_worker].null_input = TRUE; ++num_wires; start_wire_worker = start_wire_ionum = -1; } else { fputs("Saving information for later wire creation.\n", outfile); start_wire_worker = i; start_wire_ionum = j; start_wire_isinput=FALSE; } break; } } } } else if(mouse_leftstart_down && INTX_TO_FLOAT_REL(mouse_curx) > (view_workerlist[i].xpos + view_workerlist[i].width/2.0) //Check for mouse in input or output area && INTX_TO_FLOAT_REL(mouse_curx) < (view_workerlist[i].xpos + view_workerlist[i].width/2.0+INPUT_SIZE) && (INTY_TO_FLOAT_REL(mouse_cury) > (view_workerlist[i].ypos - view_workerlist[i].height/2.0)) && (INTY_TO_FLOAT_REL(mouse_cury) < (view_workerlist[i].ypos - view_workerlist[i].height/2.0 + INPUT_SIZE))) { fprintf(outfile, "Click on NULL input at %f,%f\n", INTX_TO_FLOAT_REL(mouse_curx), INTY_TO_FLOAT_REL(mouse_cury)); mouse_leftstart_down = FALSE; if(start_wire_worker >= 0) { fprintf(outfile, "Adding wire %d. output_num: %d, input_num: %d", num_wires,start_wire_ionum, -1); //Add wire view_wirelist[num_wires].start_worker = start_wire_worker; view_wirelist[num_wires].end_worker = i; view_wirelist[num_wires].output_num = start_wire_ionum;; view_wirelist[num_wires].input_num = -1; view_workerlist[i].null_input = TRUE; ++num_wires; start_wire_worker = start_wire_ionum = -1; } else { fputs("Saving information for later wire creation.\n", outfile); start_wire_worker = i; start_wire_ionum = -1; start_wire_isinput=TRUE; } } else if(mouse_leftstart_down) { fprintf(outfile, "Click at %f,%f, worker at %f,%f with size %f,%f\n", INTX_TO_FLOAT_REL(mouse_curx), INTY_TO_FLOAT_REL(mouse_cury), view_workerlist[i].xpos, view_workerlist[i].ypos, view_workerlist[i].width, view_workerlist[i].height); } if(!mouse_left_down) view_workerlist[i].grabbed= FALSE; if(mouse_left_down && view_workerlist[i].grabbed && (mouse_curx != mouse_lastx || mouse_cury != mouse_lasty)) { view_workerlist[i].xpos += INTX_TO_FLOAT_REL(mouse_curx-mouse_lastx); view_workerlist[i].ypos += INTY_TO_FLOAT_REL(mouse_cury-mouse_lasty); } drawshape(view_workerlist[i].display_type, view_workerlist[i].xpos, view_workerlist[i].ypos, view_workerlist[i].width, view_workerlist[i].height, view_workerlist[i].angle, view_workerlist[i].num_inputs, view_workerlist[i].num_outputs, view_workerlist[i].name, selected_worker==i); } glLoadIdentity(); glTranslatef(SCREEN_WIDTH_REL / (-2.0f), SCREEN_HEIGHT_REL / (-2.0f),-8.0f); glColor3f(WIRE_RED, WIRE_GREEN, WIRE_BLUE); for(i = 0; i < num_wires; ++i) { fprintf(outfile, "Wire %d starts in worker %d at output %d of %d and ends in worker %d at input %d of %d\n", i, view_wirelist[i].start_worker, view_wirelist[i].output_num, view_workerlist[view_wirelist[i].start_worker].num_outputs, view_wirelist[i].end_worker, view_wirelist[i].input_num, view_workerlist[view_wirelist[i].end_worker].num_inputs); line_startx = get_io_xpos(&view_workerlist[view_wirelist[i].start_worker], view_wirelist[i].output_num, FALSE); line_starty = get_io_ypos(&view_workerlist[view_wirelist[i].start_worker], view_wirelist[i].output_num, FALSE)-OUTPUT_SIZE; line_endx = get_io_xpos(&view_workerlist[view_wirelist[i].end_worker], view_wirelist[i].input_num, TRUE); line_endy = get_io_ypos(&view_workerlist[view_wirelist[i].end_worker], view_wirelist[i].input_num, TRUE)+OUTPUT_SIZE; x = INTX_TO_FLOAT_REL(mouse_curx); mousey = INTY_TO_FLOAT_REL(mouse_cury); if(mouse_leftstart_down) { //y = mx=b if(line_startx < line_endx) { if(x >= line_startx && x <= line_endx) { m = (line_endy-line_starty)/(line_endx-line_starty); b = line_starty; x -= line_startx; y = m*x + b; fprintf(outfile, "y: %f, m: %f, x: %f, b: %f, mousey: %f\n", y,m,x,b,mousey); if(mousey >= (y-0.05) && mousey <= (y+0.05)) { selected_wire = i; selected_worker = -1; } } } else if(line_endx > line_startx) { if(x <= line_startx && x >= line_endx) { m = (line_starty-line_endy)/(line_startx-line_endy); b = line_endy; y = m*x + b; x -= line_endx; if(mousey >= (y-0.05) && mousey <= (y+0.05)) { selected_wire = i; selected_worker = -1; } } } else //avoid divide by zero error { if(x >= (line_startx-0.05) && x <= (line_startx+0.05)) { if(line_starty > line_endy) { if(mousey >= line_endy && mousey <= line_starty) { selected_wire = i; selected_worker = -1; } } else { if(mousey <= line_endy && mousey >= line_starty) { selected_wire = i; selected_worker = -1; } } } } } if(i == selected_wire) glColor3f(SELECT_RED, SELECT_GREEN, SELECT_BLUE); fprintf(outfile, "Start (%f,%f), End (%f, %f), Mouse(%f, %f)\n", line_startx, line_starty, line_endx, line_endy, x, mousey); glBegin(GL_QUADS); glVertex2f(line_startx, line_starty); glVertex2f(line_startx+0.1, line_starty); glVertex2f(line_endx+0.1, line_endy); glVertex2f(line_endx, line_endy); glEnd(); if(i == selected_wire) glColor3f(WIRE_RED, WIRE_GREEN, WIRE_BLUE); } mouse_leftstart_down = FALSE; //view_workerlist[3].angle += 1.0; checked_mouse_pos=TRUE; if(buf_size) { glColor3f(1.0, 1.0, 1.0); glPushAttrib(GL_LIST_BIT); glListBase(glyph_base-32); glScalef(0.25,0.25,0.25); glCallLists(buf_size,GL_UNSIGNED_BYTE, new_name_buf); glPopAttrib(); } /* if(execute_active) { for(i = 0; i < num_workers; ++i) process_worker(i); if(!execute_active) { for(i = 0; i < num_datum; ++i) { if(data[i].type & 0x80) free(data[i].contents); } } } */ mouse_lastx = mouse_curx; mouse_lasty = mouse_cury; return TRUE; } GLvoid KillGLWindow(GLvoid) { if(fullscreen) { ChangeDisplaySettings(NULL, 0); ShowCursor(TRUE); } if(hRC) { glDeleteLists(glyph_base, 224); if(!wglMakeCurrent(NULL,NULL)) MessageBox(NULL, "Release of DC and RC failed.","SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); if(!wglDeleteContext(hRC)) MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); hRC = NULL; if(hDC && !ReleaseDC(hWnd,hDC)) { MessageBox(NULL,"Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); hDC = NULL; } } if(hWnd && !DestroyWindow(hWnd)) { MessageBox(NULL, "Could not Release hWnd", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); hWnd = NULL; } if(!UnregisterClass("OpenGL", hInstance)) { MessageBox(NULL, "Could Not Unregister Class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); hInstance=NULL; } } BOOL CreateGLWindow(char * title, int width, int height, int bits, BOOL fullscreenflag) { GLuint PixelFormat; WNDCLASS wc; DWORD dwExStyle; DWORD dwStyle; static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format 0, // Select Our Color Depth 0, 0, 0, 0, 0, 0, // Color Bits Ignored 0, // No Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored 16, // 16Bit Z-Buffer (Depth Buffer) 0, // No Stencil Buffer 0, // No Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored }; RECT WindowRect; WindowRect.left = (long)0; WindowRect.right = (long)width; WindowRect.top = (long)0; WindowRect.bottom=(long)height; fullscreen = fullscreenflag; hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages wc.cbClsExtra = 0; // No Extra Window Data wc.cbWndExtra = 0; // No Extra Window Data wc.hInstance = hInstance; // Set The Instance wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer wc.hbrBackground = NULL; // No Background Required For GL wc.lpszMenuName = NULL; // We Don't Want A Menu wc.lpszClassName = "OpenGL"; // Set The Class Name if (!RegisterClass(&wc)) // Attempt To Register The Window Class { MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; // Exit And Return FALSE } if (fullscreen) // Attempt Fullscreen Mode? { DEVMODE dmScreenSettings; // Device Mode memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure dmScreenSettings.dmPelsWidth = width; // Selected Screen Width dmScreenSettings.dmPelsHeight = height; // Selected Screen Height dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) { // If The Mode Fails, Offer Two Options. Quit Or Run In A Window. if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) { fullscreen=FALSE; // Select Windowed Mode (Fullscreen=FALSE) } else { // Pop Up A Message Box Letting User Know The Program Is Closing. MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP); return FALSE; // Exit And Return FALSE } } } if (fullscreen) // Are We Still In Fullscreen Mode? { dwExStyle=WS_EX_APPWINDOW; // Window Extended Style dwStyle=WS_POPUP; // Windows Style ShowCursor(FALSE); // Hide Mouse Pointer } else { dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style } AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window "OpenGL", // Class Name title, // Window Title WS_CLIPSIBLINGS | // Required Window Style WS_CLIPCHILDREN | // Required Window Style dwStyle, // Selected Window Style 0, 0, // Window Position WindowRect.right-WindowRect.left, // Calculate Adjusted Window Width WindowRect.bottom-WindowRect.top, // Calculate Adjusted Window Height NULL, // No Parent Window NULL, // No Menu hInstance, // Instance NULL))) // Don't Pass Anything To WM_CREATE { KillGLWindow(); // Reset The Display MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; // Return FALSE } pfd.cColorBits = bits; if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context? { KillGLWindow(); // Reset The Display MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; // Return FALSE } if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format? { KillGLWindow(); // Reset The Display MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; // Return FALSE } if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format? { KillGLWindow(); // Reset The Display MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; // Return FALSE } if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context? { KillGLWindow(); // Reset The Display MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; // Return FALSE } if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context { KillGLWindow(); // Reset The Display MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; // Return FALSE } ShowWindow(hWnd,SW_SHOW); // Show The Window SetForegroundWindow(hWnd); // Slightly Higher Priority SetFocus(hWnd); // Sets Keyboard Focus To The Window ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen if (!InitGL()) // Initialize Our Newly Created GL Window { KillGLWindow(); // Reset The Display MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; // Return FALSE } return TRUE; // Success } LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window UINT uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam) // Additional Message Information { int i; worker_def * def; FILE * loadfile; char * code; int size; switch (uMsg) // Check For Windows Messages { case WM_ACTIVATE: // Watch For Window Activate Message { if (!HIWORD(wParam)) // Check Minimization State { active=TRUE; // Program Is Active } else { active=FALSE; // Program Is No Longer Active } return 0; // Return To The Message Loop } case WM_SYSCOMMAND: // Intercept System Commands { switch (wParam) // Check System Calls { case SC_SCREENSAVE: // Screensaver Trying To Start? case SC_MONITORPOWER: // Monitor Trying To Enter Powersave? return 0; // Prevent From Happening } break; // Exit } case WM_CLOSE: // Did We Receive A Close Message? { PostQuitMessage(0); // Send A Quit Message return 0; // Jump Back } case WM_KEYDOWN: // Is A Key Being Held Down? { if(wParam == VK_BACK && buf_size > 0) --buf_size; else if(wParam == VK_F5 && !execute_active) { deflist[current_def].implement_func->num_workers = num_workers; deflist[current_def].implement_func->num_wires = num_wires; fprintf(outfile, "Starting execution.\n"); interp_start(-1,FALSE,0,NULL); } else if(wParam == VK_RETURN && buf_size > 0) { text_buf_size = buf_size; memcpy(text_buf, new_name_buf, buf_size); buf_size = 0; if(memcmp(text_buf, "Save:", strlen("Save:")) == 0) { text_buf[text_buf_size]='\0'; deflist[current_def].implement_func->num_workers = num_workers; deflist[current_def].implement_func->num_wires = num_wires; save_program(text_buf + strlen("Save:")); text_buf_size = 0; } else if(memcmp(text_buf, "Load:", strlen("Load:")) == 0) { text_buf[text_buf_size]='\0'; load_program(text_buf + strlen("Load:")); view_workerlist = deflist[0].implement_func->workerlist; view_wirelist = deflist[0].implement_func->wirelist; num_workers = deflist[0].implement_func->num_workers; num_wires = deflist[0].implement_func->num_wires; text_buf_size = 0; } else if (memcmp(text_buf, "View:", strlen("View:")) == 0) { text_buf[text_buf_size]='\0'; deflist[current_def].implement_func->num_workers = num_workers; deflist[current_def].implement_func->num_wires = num_wires; i = find_worker(text_buf+strlen("View:"), NULL, NULL); if(i < 0) current_def = create_worker(text_buf+strlen("View:"), 0, 0, USER_FLAG | WORKER_TYPE) - deflist; else current_def = i; num_workers = deflist[current_def].implement_func->num_workers; num_wires = deflist[current_def].implement_func->num_wires; view_workerlist = deflist[current_def].implement_func->workerlist; view_wirelist = deflist[current_def].implement_func->wirelist; text_buf_size = 0; selected_worker = -1; } else if(memcmp(text_buf, "Import:", strlen("Import:")) == 0) { deflist[current_def].implement_func->num_workers = num_workers; deflist[current_def].implement_func->num_wires = num_wires; text_buf[text_buf_size]='\0'; loadfile = fopen(text_buf+strlen("Import:"), "rb"); fseek(loadfile, 0, SEEK_END); size = ftell(loadfile); fseek(loadfile, 0, SEEK_SET); code = malloc(size+1); fread(code, 1, size, loadfile); parse(code, size); } } else if(wParam == VK_DELETE) { if(selected_worker != -1) { for(i = 0; i < num_wires; ++i) { if(view_wirelist[i].start_worker == selected_worker || view_wirelist[i].end_worker == selected_worker) { view_wirelist[i] = view_wirelist[num_wires-1]; --num_wires; --i; } } view_workerlist[selected_worker] = view_workerlist[num_workers-1]; for(i = 0; i < num_wires; ++i) { if(view_wirelist[i].start_worker == num_workers-1) view_wirelist[i].start_worker = selected_worker; if(view_wirelist[i].end_worker == num_workers-1) view_wirelist[i].end_worker = selected_worker; } --num_workers; selected_worker = -1; } } keys[wParam] = TRUE; // If So, Mark It As TRUE return 0; // Jump Back } case WM_KEYUP: // Has A Key Been Released? { keys[wParam] = FALSE; // If So, Mark It As FALSE return 0; // Jump Back } case WM_SIZE: // Resize The OpenGL Window { ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height return 0; // Jump Back } case WM_RBUTTONDOWN: { view_workerlist[num_workers].xpos = INTX_TO_FLOAT_REL(GET_X_LPARAM(lParam)); view_workerlist[num_workers].ypos = INTY_TO_FLOAT_REL(480-GET_Y_LPARAM(lParam)); view_workerlist[num_workers].height = 0.25; view_workerlist[num_workers].grabbed=FALSE; if(buf_size > strlen("Data:") && memcmp("Data:", new_name_buf, strlen("Data:")) == 0) { view_workerlist[num_workers].display_type=1;//Rectangle view_workerlist[num_workers].type=0;//Constant view_workerlist[num_workers].num_inputs=0;//Constants don't have inputs view_workerlist[num_workers].num_outputs=1;//Constants have one output view_workerlist[num_workers].null_input = FALSE; memcpy(view_workerlist[num_workers].name, new_name_buf+strlen("Data:"), buf_size-strlen("Data:")); view_workerlist[num_workers].name[buf_size-strlen("Data:")]='\0'; view_workerlist[num_workers].width = ((double)(buf_size-strlen("Data:"))+0.5) * INPUT_SIZE; ++num_workers; buf_size = 0; } else if(buf_size > strlen("Room:") && memcmp("Room:", new_name_buf, strlen("Room:")) == 0) { view_workerlist[num_workers].type=1;//Room view_workerlist[num_workers].display_type=1;//Rectangle view_workerlist[num_workers].num_inputs=1; view_workerlist[num_workers].num_outputs=1; view_workerlist[num_workers].null_input = FALSE; memcpy(view_workerlist[num_workers].name, new_name_buf+strlen("Room:"), buf_size-strlen("Room:")); view_workerlist[num_workers].name[buf_size-strlen("Room:")]='\0'; view_workerlist[num_workers].width = ((double)(buf_size-strlen("Room:"))+0.5) * INPUT_SIZE; ++num_workers; buf_size = 0; } else if(buf_size > strlen("Input:") && memcmp("Input:", new_name_buf, strlen("Input:")) == 0) { deflist[current_def].implement_func->num_workers = num_workers; new_name_buf[buf_size] = '\0'; MessageBox(NULL, new_name_buf,"Error",MB_OK); add_input(deflist+current_def, new_name_buf + strlen("Input:"), INTX_TO_FLOAT_REL(GET_X_LPARAM(lParam)), INTY_TO_FLOAT_REL(480-GET_Y_LPARAM(lParam))); num_workers = deflist[current_def].implement_func->num_workers; } else if(buf_size > strlen("Output:") && memcmp("Output:", new_name_buf, strlen("Output:")) == 0) { deflist[current_def].implement_func->num_workers = num_workers; new_name_buf[buf_size] = '\0'; add_output(deflist+current_def, new_name_buf + strlen("Output:"), INTX_TO_FLOAT_REL(GET_X_LPARAM(lParam)), INTY_TO_FLOAT_REL(480-GET_Y_LPARAM(lParam))); num_workers = deflist[current_def].implement_func->num_workers; } else if(buf_size > strlen("Express:") && memcmp("Express:", new_name_buf, strlen("Express:")) == 0) { deflist[current_def].implement_func->num_workers = num_workers; new_name_buf[buf_size] = '\0'; def = create_worker(new_name_buf+strlen("Express:"), 0, 0, USER_FLAG | WORKER_TYPE); parse_body(def, new_name_buf+strlen("Express:"), buf_size-strlen("Express:")); add_worker_to_def(deflist+current_def, def-deflist, INTX_TO_FLOAT_REL(GET_X_LPARAM(lParam)), INTY_TO_FLOAT_REL(480-GET_Y_LPARAM(lParam))); num_workers = deflist[current_def].implement_func->num_workers; buf_size = 0; } else { memcpy(view_workerlist[num_workers].name, new_name_buf, buf_size); view_workerlist[num_workers].name[buf_size] = '\0'; for(i = 0; i < num_defs; ++i) { fprintf(outfile, "Comparing %s with %s(%d)\n", view_workerlist[num_workers].name, deflist[i].name, i); if(strcmp(view_workerlist[num_workers].name, deflist[i].name)==0) { view_workerlist[num_workers].display_type=2;//Trapezoid view_workerlist[num_workers].type=2;//Worker view_workerlist[num_workers].num_inputs=deflist[i].num_inputs; view_workerlist[num_workers].num_outputs=deflist[i].num_outputs; view_workerlist[num_workers].null_input = FALSE; view_workerlist[num_workers].value_index = i; view_workerlist[num_workers].width = ((double)buf_size+0.5) * INPUT_SIZE; ++num_workers; buf_size = 0; break; } } if(i >= num_defs) { strcpy(new_name_buf, "I don't know a worker with that name."); buf_size = strlen(new_name_buf); } } if(view_workerlist[num_workers-1].width <= (double)view_workerlist[num_workers-1].num_outputs * OUTPUT_SIZE) view_workerlist[num_workers-1].width = (double)view_workerlist[num_workers-1].num_outputs * (OUTPUT_SIZE*1.1); if(view_workerlist[num_workers-1].width <= (double)view_workerlist[num_workers-1].num_inputs * INPUT_SIZE) view_workerlist[num_workers-1].width = (double)view_workerlist[num_workers-1].num_inputs * (INPUT_SIZE*1.1); break; } case WM_LBUTTONDOWN: { mouse_leftstart_down=mouse_left_down=TRUE; mouse_lastx = mouse_curx = GET_X_LPARAM(lParam); mouse_lasty = mouse_cury = 480-GET_Y_LPARAM(lParam); checked_mouse_pos=FALSE; return 0; } case WM_LBUTTONUP: { mouse_leftstart_down=mouse_left_down=FALSE; return 0; } case WM_MOUSEMOVE: { //If no one has checked the mouse position vars, this could cause bugs if(checked_mouse_pos) { mouse_lastx = mouse_curx; mouse_lasty = mouse_cury; } mouse_curx = GET_X_LPARAM(lParam); mouse_cury = 480-GET_Y_LPARAM(lParam); checked_mouse_pos=FALSE; return 0; } case WM_CHAR: { if(wParam >= 0x20) { new_name_buf[buf_size++]=wParam&0xFF; } return 0; } } // Pass All Unhandled Messages To DefWindowProc return DefWindowProc(hWnd,uMsg,wParam,lParam); } VOID CALLBACK DoFrame(HWND myhWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { if(active) { DrawGLScene(); // Draw The Scene SwapBuffers(hDC); // Swap Buffers (Double Buffering) } } int WINAPI WinMain( HINSTANCE hInstance, // Instance HINSTANCE hPrevInstance, // Previous Instance LPSTR lpCmdLine, // Command Line Parameters int nCmdShow) // Window Show State { MSG msg; // Windows Message Structure BOOL done=FALSE; // Bool Variable To Exit Loop // Ask The User Which Screen Mode They Prefer if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO) { fullscreen=FALSE; // Windowed Mode } // Create Our OpenGL Window if (!CreateGLWindow("Visuality",640,480,16,fullscreen)) { return 0; // Quit If Window Was Not Created } initworkers(); view_workerlist = deflist[0].implement_func->workerlist; view_wirelist = deflist[0].implement_func->wirelist; outfile = fopen("output.txt", "w"); SetTimer(hWnd, 1, 17, DoFrame); while(!done) // Loop That Runs Until done=TRUE { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting? { if (msg.message==WM_QUIT) // Have We Received A Quit Message? { done=TRUE; // If So done=TRUE } else // If Not, Deal With Window Messages { TranslateMessage(&msg); // Translate The Message DispatchMessage(&msg); // Dispatch The Message } } // Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene() if (active) // Program Active? { if (keys[VK_ESCAPE]) // Was ESC Pressed? { done=TRUE; // ESC Signalled A Quit } else // Not Time To Quit, Update Screen { } if (keys[VK_F1]) // Is F1 Being Pressed? { keys[VK_F1]=FALSE; // If So Make Key FALSE KillTimer(hWnd, 1); KillGLWindow(); // Kill Our Current Window fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode // Recreate Our OpenGL Window if (!CreateGLWindow("Rini's Love Quest",640,480,16,fullscreen)) { return 0; // Quit If Window Was Not Created } SetTimer(hWnd, 1, 17, DoFrame); } } Sleep(0); } KillTimer(hWnd, 1); // Shutdown KillGLWindow(); // Kill The Window return (msg.wParam); // Exit The Program }