📄 main.cpp
字号:
#define ALLEGRO_STATICLINK
/*
gRPG by Ryan Broomfield 2003
Contact: AIM - RyanBroomfield
email - ryan@shippysite.com
website - http://www.shippysite.com
Copyright (C) 2003 Ryan Broomfield ALL RIGHTS RESERVED
no theefin'
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <allegro.h>
#ifdef _WIN32
#include <winalleg.h>
#endif
#include <fstream>
#include "types.h"
#include "functions.h"
#include "entity.h"
#include "context.h"
class GRPGLOG
{
public:
PACKFILE *bleh;
int operational;
GRPGLOG()
{
operational=0;
}
void start(char *name)
{
operational = 0;
bleh = pack_fopen(name,"w");
if(bleh!=NULL) operational=1;
}
void end()
{
if(operational==1) pack_fclose(bleh);
operational = 0;
}
void write(char *dude)
{
TRACE(dude);
if(operational==0) return;
pack_fputs(dude, bleh);
pack_fputs("\n",bleh);
}
};
GRPGLOG gamelog;
volatile int synchobjects = 0;
void syncher()
{
++synchobjects;
}
END_OF_FUNCTION(syncher)
int osynchframes = 0;
int objectmax;
int DIE = 0;
//BASIC VIDEO BITMAP STRUCTURES
BITMAP *FastTile = NULL;
//Stores our tiles 256x1024
BITMAP *SolidTile = NULL;
//STores a 32x32 image for overlaying solid tiles in the editor
BITMAP *SolidObject = NULL;
//Stores a 32x32 image for overlaying objects in the editor
//Stores the frames for our objects in ram
BITMAP *FastFont = NULL;
BITMAP *FastSFont = NULL;
//Font
BITMAP *vidbuffer[2] = { NULL , NULL };
//Front and Back video buffers
BITMAP *dirtytiles = NULL;
//Optimized, aligned dirty tile buffer (640+32,480+32)
BITMAP *gfxmessage = NULL;
//Stores our message box bitmap
//Unused palette for future 256 color mode
PALETTE pal;
//Midi handle for the background music
MIDI *ffover = NULL;
//Max Number of object sprites that we can load for grpg
//Lookup table for facing direction tiles
//Looks up faceway[facingx][facingy] and returns the Y offset of the frame in FastObject
int faceway[3][3];
//Very Low Update drawn buffers for layer 1 and layer 2
//If a tile is already drawn it's not drawn, if not it's drawn adn then the tile # stored
//in the drawn array
int drawn[21][16];
int drawn2[21][16];
//Stores Tile Animation Frame #'s and Delay frame #'s for each of the 256 possible tiles
TILEANIM tileanimation[256];
//Current page handle for the back buffer (changes with each blit)
int page_num = 1;
//Stores fullscreen (1 == ON, 0 == OFF
int fullscreen = 0;
//Stores VSYNC (1 == ON, 0 == OFF
int vertsync = 0;
//Stores software drawing mode toggle (1 == ON, 0 == OFF
int gravyhack = 0;
//Stores whether or not each layer is drawn in the editor
// 1 == YES, 0 == NO
int drawlayer[2] = { 1 , 1 };
ENVIRONMENT map;
//Maps for layer 1,layer 2, and the object layer
//Used for general engine timing to sync to 100Hz
int count = 0;
int syncedtimer = 0;
//Total number of frames *drawn*
int frames = 0;
//Total number of frames in the object system executed
int oframes = 0;
//Status of Editor (1 == ON , 0 == OFF)
int editortoggle = 0;
//holds ms from GetTickCount + delay to make sure the editor isn't toggled too fast
int editortime = 0;
//Current tile in the editor
int currtile = 0;
//Current layer in the editor
int currlayer = 1;
//Current mousescrollwheel position
int currmousez = 0;
//Holds ms from GetTickCount + delay to make sure the tile isn't changed too fast
//Also used to prevent other keys in the editor from getting pressed too fast
int tilechangedelay = 0;
//0 stores the tile as BOTTOM in the editor, 1 stores the tile as TOP in the editor
int topdraw = 0;
//Stores the frames per second
int ofps = 0;
int olast=0;
int fps = 0;
//2d CAMERA for our engine
CAMVIEWPORT camera;
//Stores our text box
BOXSTRUCT textbox;
SWAPPER swapper;
//:installmessage "installmessage"
//:say "say"
//Set up our little objects :D
int scenario_loaded = oframes;
int objectfocus = 0;
char current_scenario[256];
char current_physical_scenario[256];
ENTITY *OBJECTS;
BITMAP **FastObject;
CONTEXTPROMPT database;
void* GetEObject(int phandle)
{
for(int i=0;i<objectmax;++i)
{
if(OBJECTS[i].enginehandle == phandle)
{
return (void*)(&OBJECTS[i]);
}
}
return NULL;
}
void SendObjectMessage(int number, int message, int fromobj)
{
if(number == fromobj || number == -1 || fromobj == -1) return;
if(OBJECTS[number].lastmessage[message] >= oframes) return;
if(OBJECTS[number].messageproc != -1)
{
THREAD *handler = NULL;
switch(message)
{
case MSG_TOUCH:
handler = OBJECTS[number].vm.processes->AddThread(OBJECTS[number].messageproc);
if(handler!=NULL)
{
handler->stack[handler->stackpointer] = message;
++handler->stackpointer;
}
OBJECTS[number].lastmessage[message] = oframes + 100;
break;
case MSG_TALK:
if(fromobj == objectfocus)
{
handler = OBJECTS[number].vm.processes->AddThread(OBJECTS[number].messageproc);
if(handler!=NULL)
{
handler->stack[handler->stackpointer] = message;
++handler->stackpointer;
}
OBJECTS[number].lastmessage[message] = oframes + 10;
}
break;
default:
OBJECTS[number].lastmessage[message] = oframes + 1;
}
}
}
bool intersects(int r1x1, int r1x2, int r1y1, int r1y2, int r2x1, int r2x2, int r2y1, int r2y2)
{
if ((r1x1 >= r2x2) || (r1x2 <= r2x1) || (r1y1 >= r2y2) || (r1y2 <= r2y1)) return false;
if ((r1x1 < r2x1) && (r1x2 > r2x2)) return (r1y1 < r2y2) && (r1y2 > r2y1);
if ((r1y1 < r2y1) && (r1y2 > r2y2)) return (r1x1 < r2x2) && (r1x2 > r2x1);
return true;
}
void CreateMessageBox(char *pmessage, int fromobj)
{
if (textbox.status > 0) return;
textbox.fromobj = fromobj;
textbox.x = 304;
textbox.x2 = 336;
textbox.y = 64;
textbox.y2 = 96;
textbox.status = 1;
textbox.charposx = 0;
textbox.charposy = 0;
textbox.prompt = 0;
textbox.delay=0;
textbox.message = pmessage;
textbox.currchar = 0;
textbox.start = 0;
for(int i=0;i < 8;++i)
{
memset(&textbox.grid[i][0],0,40);
}
}
void ShrinkMessageBox()
{
textbox.x += 16;
textbox.y += 16;
if( textbox.x > 304 ) textbox.x = 304;
if( textbox.y > 64 ) textbox.y = 64;
textbox.x2 -= 16;
textbox.y2 -= 16;
if( textbox.x2 < 336 ) textbox.x2 = 336;
if( textbox.y2 < 96 ) textbox.y2 = 96;
if( textbox.x == 304 && textbox.y == 64
&& textbox.x2 == 336 && textbox.y2 == 96 ) textbox.status = 0;
}
void GrowMessageBox()
{
textbox.x -= 16;
textbox.y -= 16;
if( textbox.x < 0 ) textbox.x = 0;
if( textbox.y < 0 ) textbox.y = 0;
textbox.x2 += 16;
textbox.y2 += 16;
if( textbox.x2 > 624) textbox.x2 = 624;
if( textbox.y2 > 144) textbox.y2 = 144;
if( textbox.x == 0 && textbox.y == 0
&& textbox.x2 == 624 && textbox.y2 == 144 ) textbox.status = 2;
}
void DrawBox(int x1, int y1, int x2, int y2)
{
int renderblockx , renderblocky;
//Draws the 4 corners of the message box
masked_blit( gfxmessage , vidbuffer[page_num] , 0 , 0 , x1 , y1 , 16 , 16 );
masked_blit( gfxmessage , vidbuffer[page_num] , 48 , 0 , x2 , y1, 16 , 16 );
masked_blit( gfxmessage , vidbuffer[page_num] , 0 , 48 , x1 , y2 , 16 , 16 );
masked_blit( gfxmessage , vidbuffer[page_num] , 48 , 48 , x2 , y2 , 16 , 16 );
int blockstodrawx = ( x2 - x1 ) / 16;
int blockstodrawy = ( y2 - y1 ) / 16;
//Draws the Top Line
for( renderblockx = 1 ; renderblockx <= blockstodrawx - 1 ; renderblockx++ )
{
blit( gfxmessage, vidbuffer[page_num], 16, 0,
x1 + renderblockx * 16 , y1 , 16 , 16 );
}
//Draws the 2 Sides
for( renderblocky = 1 ; renderblocky <= blockstodrawy - 1 ; renderblocky++ )
{
masked_blit( gfxmessage , vidbuffer[page_num] , 0 , 16,
x1 , y1 + renderblocky * 16 , 16 , 16 );
masked_blit( gfxmessage , vidbuffer[page_num] , 48 , 16,
x2 , y1 + renderblocky * 16 , 16 , 16 );
}
//Draws the Body
for( renderblocky = 1 ; renderblocky <= blockstodrawy - 1 ; renderblocky++ )
{
for( renderblockx = 1 ; renderblockx <= blockstodrawx - 1 ; renderblockx++ )
{
blit( gfxmessage , vidbuffer[page_num] , renderblockx&1?32:16, renderblocky&1?32:16 ,
x1 + renderblockx * 16 , y1 + renderblocky * 16 , 16,16);
}
}
//Draws the Bottom
for( renderblockx = 1 ; renderblockx <= blockstodrawx - 1 ; renderblockx++ )
{
masked_blit( gfxmessage, vidbuffer[page_num] , 16 , 48,
x1 + renderblockx * 16 , y2 , 16 , 16 );
}
}
void DrawScenarioTitle()
{
int centerx = ((38 - strlen(current_scenario)) / 2) * 16;
DrawBox(32,0,592,32);
PrintMessageText(current_scenario, centerx+16, 16,0);
}
void RenderBox()
{
if(textbox.status == 0) return;
DrawBox(textbox.x,textbox.y,textbox.x2,textbox.y2);
if(textbox.status!=2) return;
//Draws the Message Box in its current state (general routine)
for(int i=0;i<8;++i) PrintMessageText(&textbox.grid[i][0],16,16 + (16*i),0);
if(textbox.fromobj>0)
{
if(OBJECTS[textbox.fromobj].spr>-1)
{
DrawBox(0,160,144,304);
blit(FastObject[OBJECTS[textbox.fromobj].spr], vidbuffer[page_num], 256, 0, 16,176 , 128 , 128 );
}
else
{
DrawBox(0,160,48,208);
masked_blit(FastTile, vidbuffer[page_num], (-OBJECTS[textbox.fromobj].spr&15)<<5, ((-OBJECTS[textbox.fromobj].spr)/16)<<5,16,176, 32, 32);
}
}
if(textbox.prompt==1)
{
DrawBox(288,160,624,192);
PrintMessageText("MORE, PRESS ARROWS",320,176,0);
}
if(textbox.prompt==2)
{
DrawBox(400,160,624,192);
PrintMessageText("PRESS SPACE",432,176,0);
}
}
void PrintMessageChar(char text, int x, int y, int smallf)
{
if(text<0) return;
if(smallf == 1) masked_blit(FastSFont,vidbuffer[page_num],0,text*8,x,y,8,8);
else masked_blit(FastFont,vidbuffer[page_num],0,text*16,x,y,16,16);
}
void PrintMessageText(char *text, int x, int y, int smallf)
{
int offset=0;
int xdraw=x;
char bleh;
while (text[offset]!=0)
{
bleh=text[offset];
if(bleh<0) break;
if(smallf==1)
{
masked_blit(FastSFont,vidbuffer[page_num],0,bleh*8,xdraw,y,8,8);
xdraw+=8;
}
else
{
masked_blit(FastFont,vidbuffer[page_num],0,bleh*16,xdraw,y,16,16);
xdraw+=16;
}
++offset;
}
}
void TextAddChar(char toadd)
{
if(toadd==10)
{
textbox.charposx=0;
++textbox.charposy;
++textbox.start;
}
else
{
textbox.grid[textbox.charposy][textbox.charposx] = toadd;
++textbox.charposx;
if(textbox.charposx>37)
{
textbox.charposx=0;
++textbox.charposy;
++textbox.start;
}
}
if(textbox.charposy>7)
{
strcpy(&textbox.grid[0][0],&textbox.grid[1][0]);
strcpy(&textbox.grid[1][0],&textbox.grid[2][0]);
strcpy(&textbox.grid[2][0],&textbox.grid[3][0]);
strcpy(&textbox.grid[3][0],&textbox.grid[4][0]);
strcpy(&textbox.grid[4][0],&textbox.grid[5][0]);
strcpy(&textbox.grid[5][0],&textbox.grid[6][0]);
strcpy(&textbox.grid[6][0],&textbox.grid[7][0]);
memset(&textbox.grid[7][0],0,40);
textbox.charposy = 7;
}
if(textbox.start > 6)
{
textbox.prompt = 1;
do
{
}
while(key[KEY_DOWN] || key[KEY_UP] || key[KEY_LEFT] || key[KEY_RIGHT]);
textbox.start = 0;
}
}
void ExecMessageBox()
{
//If the box is shrinking, shrink it
//If the box is growing, grow it
if(textbox.delay>0)
{
--textbox.delay;
if(!(key[KEY_DOWN] || key[KEY_UP] || key[KEY_LEFT] || key[KEY_RIGHT])) return;
}
if(textbox.prompt==1)
{
if(key[KEY_DOWN] || key[KEY_UP] || key[KEY_LEFT] || key[KEY_RIGHT]) textbox.prompt = 0;
return;
}
if(textbox.prompt==2)
{
if(key[KEY_SPACE])
{
textbox.prompt = 0;
textbox.status = 3;
}
}
switch ( textbox.status )
{
case 0:
break;
case 1:
GrowMessageBox();
break;
case 2:
switch(textbox.message[textbox.currchar])
{
case 0:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -