Enable the Save Game menu (exits game after save)
This commit is contained in:
parent
7b4e50b1c5
commit
db04c99446
1
README
1
README
|
@ -31,6 +31,7 @@ Technical support TODO:
|
|||
-> Built-in overclocking?
|
||||
-> SDL2 debug version support?
|
||||
-> Darken background in menu (some code does that somewhere?)
|
||||
-> Rate-limit
|
||||
|
||||
CGDoom used to be compiled with the mini-SDK. However, it's become quite
|
||||
difficult to get a copy of that. Instead, this port is built with a modified
|
||||
|
|
|
@ -270,6 +270,7 @@ void D_DoomLoop (void)
|
|||
M_Ticker (); //Menu ticker
|
||||
|
||||
G_Ticker (); //Game ticker
|
||||
if (fuck) break; //Quick exit after save game
|
||||
|
||||
gametic++;
|
||||
|
||||
|
|
|
@ -460,7 +460,10 @@ void G_Ticker (void)
|
|||
break;
|
||||
case ga_savegame:
|
||||
G_DoSaveGame ();
|
||||
break;
|
||||
/* After saving the game, the storage memory is shuffled, we need to
|
||||
leave and we need to do it quickly */
|
||||
I_Quit();
|
||||
return;
|
||||
case ga_playdemo:
|
||||
G_DoPlayDemo ();
|
||||
break;
|
||||
|
@ -933,14 +936,60 @@ void G_DoLoadGame (void)
|
|||
//
|
||||
void G_SaveGame( int slot, char* description )
|
||||
{
|
||||
(void)slot;
|
||||
(void)description;
|
||||
savegameslot = slot;
|
||||
CGDstrcpy (savedescription, description);
|
||||
sendsave = true;
|
||||
}
|
||||
|
||||
void G_DoSaveGame (void)
|
||||
{
|
||||
}
|
||||
char name[50];
|
||||
char name2[VERSIONSIZE];
|
||||
char* description;
|
||||
int length;
|
||||
int i;
|
||||
|
||||
sprintf(name, SAVEGAMENAME "%d.dsg", savegameslot);
|
||||
description = savedescription;
|
||||
|
||||
save_p = savebuffer = screens[1]+0x4000;
|
||||
|
||||
memcpy (save_p, description, SAVESTRINGSIZE);
|
||||
save_p += SAVESTRINGSIZE;
|
||||
memset (name2,0,sizeof(name2));
|
||||
sprintf (name2,"version %i",VERSION);
|
||||
memcpy (save_p, name2, VERSIONSIZE);
|
||||
save_p += VERSIONSIZE;
|
||||
|
||||
*save_p++ = gameskill;
|
||||
*save_p++ = gameepisode;
|
||||
*save_p++ = gamemap;
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
*save_p++ = playeringame[i];
|
||||
*save_p++ = leveltime>>16;
|
||||
*save_p++ = leveltime>>8;
|
||||
*save_p++ = leveltime;
|
||||
|
||||
P_ArchivePlayers ();
|
||||
P_ArchiveWorld ();
|
||||
P_ArchiveThinkers ();
|
||||
P_ArchiveSpecials ();
|
||||
|
||||
*save_p++ = 0x1d; // consistancy marker
|
||||
|
||||
length = save_p - savebuffer;
|
||||
if (length > SAVEGAMESIZE)
|
||||
I_Error ("Savegame buffer overrun");
|
||||
|
||||
M_WriteFile (name, savebuffer, length);
|
||||
|
||||
gameaction = ga_nothing;
|
||||
savedescription[0] = 0;
|
||||
|
||||
static char msg[32];
|
||||
sprintf(msg, GGSAVED " (%d kB)", length >> 10);
|
||||
players[consoleplayer].message = msg;
|
||||
}
|
||||
|
||||
//
|
||||
// G_InitNew
|
||||
|
|
|
@ -276,25 +276,31 @@ void I_StartTic (void)
|
|||
// Special keys
|
||||
//---
|
||||
|
||||
/* This variable is set in m_menu.c while typing save file names */
|
||||
extern int saveStringEnter;
|
||||
|
||||
UpdateKeyboardState();
|
||||
|
||||
/* Capture events for special keys */
|
||||
if (KeyWasJustPressed(SKEY_CHEAT))
|
||||
CGCheat();
|
||||
if (KeyWasJustPressed(SKEY_DECVP))
|
||||
R_SetViewSizeChange(-1);
|
||||
if (KeyWasJustPressed(SKEY_INCVP))
|
||||
R_SetViewSizeChange(1);
|
||||
if (KeyWasJustPressed(SKEY_NOCLIP))
|
||||
CGSwitchClip();
|
||||
if (KeyWasJustPressed(SKEY_GAMMA))
|
||||
CGCycleGamma();
|
||||
if (KeyWasJustPressed(SKEY_FREEMEM))
|
||||
CGFreeMem();
|
||||
if (KeyWasJustPressed(SKEY_FPSCOUNTER))
|
||||
fpscounteractive = !fpscounteractive;
|
||||
if (KeyWasJustPressed(SKEY_FRAMESKIP))
|
||||
CGRefreshSwitch();
|
||||
if(!saveStringEnter)
|
||||
{
|
||||
/* Capture events for special keys */
|
||||
if(KeyWasJustPressed(SKEY_CHEAT))
|
||||
CGCheat();
|
||||
if(KeyWasJustPressed(SKEY_DECVP))
|
||||
R_SetViewSizeChange(-1);
|
||||
if(KeyWasJustPressed(SKEY_INCVP))
|
||||
R_SetViewSizeChange(1);
|
||||
if(KeyWasJustPressed(SKEY_NOCLIP))
|
||||
CGSwitchClip();
|
||||
if(KeyWasJustPressed(SKEY_GAMMA))
|
||||
CGCycleGamma();
|
||||
if(KeyWasJustPressed(SKEY_FREEMEM))
|
||||
CGFreeMem();
|
||||
if(KeyWasJustPressed(SKEY_FPSCOUNTER))
|
||||
fpscounteractive = !fpscounteractive;
|
||||
if(KeyWasJustPressed(SKEY_FRAMESKIP))
|
||||
CGRefreshSwitch();
|
||||
}
|
||||
|
||||
//---
|
||||
// Profiler
|
||||
|
@ -303,7 +309,7 @@ void I_StartTic (void)
|
|||
/* Number of ticks left before reporting results */
|
||||
static int profiler_ticks = -1;
|
||||
|
||||
if (KeyWasJustPressed(SKEY_PROFILER)) {
|
||||
if (!saveStringEnter && KeyWasJustPressed(SKEY_PROFILER)) {
|
||||
prof_t *counters = (prof_t *)&CGD_Perf;
|
||||
for(int i = 0; i < sizeof CGD_Perf / sizeof (prof_t); i++) {
|
||||
counters[i] = prof_make();
|
||||
|
@ -322,13 +328,25 @@ void I_StartTic (void)
|
|||
// Normal keys
|
||||
//---
|
||||
|
||||
static int keys[] = {
|
||||
/* Sets of keys depending on input mode. Each set must only consist of keys
|
||||
that don't overlap */
|
||||
static const int base_keys[] = {
|
||||
KEY_LEFTARROW, KEY_RIGHTARROW, KEY_UPARROW, KEY_DOWNARROW,
|
||||
KEY_RCTRL, KEY_TAB, KEY_PAUSE, KEY_SLEFTARROW, KEY_SRIGHTARROW,
|
||||
KEY_ESCAPE, KEY_ENTER,
|
||||
' ', '1', '2', '3', '4', '5', '6', '7',
|
||||
0
|
||||
};
|
||||
static const int input_keys[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
||||
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
KEY_BACKSPACE, KEY_ESCAPE, KEY_ENTER,
|
||||
0
|
||||
};
|
||||
|
||||
const int *keys = base_keys;
|
||||
if(saveStringEnter)
|
||||
keys = input_keys;
|
||||
|
||||
/* Emit events for all changes */
|
||||
for(int i = 0; keys[i]; i++)
|
||||
|
|
208
cgdoom/m_menu.c
208
cgdoom/m_menu.c
|
@ -111,7 +111,7 @@ int saveStringEnter;
|
|||
int saveSlot; // which slot to save in
|
||||
int saveCharIndex; // which char we're editing
|
||||
// old save description before edit
|
||||
//char saveOldString[SAVESTRINGSIZE];
|
||||
char saveOldString[SAVESTRINGSIZE];
|
||||
|
||||
boolean inhelpscreens;
|
||||
boolean menuactive;
|
||||
|
@ -120,7 +120,7 @@ boolean menuactive;
|
|||
#define LINEHEIGHT 16
|
||||
|
||||
extern boolean sendpause;
|
||||
//char savegamestrings[10][SAVESTRINGSIZE];
|
||||
char savegamestrings[10][SAVESTRINGSIZE];
|
||||
|
||||
char endstring[160];
|
||||
|
||||
|
@ -205,8 +205,8 @@ void M_DrawNewGame(void);
|
|||
void M_DrawEpisode(void);
|
||||
void M_DrawOptions(void);
|
||||
//void M_DrawSound(void);
|
||||
//void M_DrawLoad(void);
|
||||
//void M_DrawSave(void);
|
||||
void M_DrawLoad(void);
|
||||
void M_DrawSave(void);
|
||||
|
||||
void M_DrawSaveLoadBorder(int x,int y);
|
||||
void M_SetupNextMenu(menu_t *menudef);
|
||||
|
@ -410,7 +410,7 @@ enum
|
|||
load6,
|
||||
load_end
|
||||
} load_e;
|
||||
/*
|
||||
|
||||
menuitem_t LoadMenu[]=
|
||||
{
|
||||
{1,"", M_LoadSelect,'1'},
|
||||
|
@ -453,38 +453,40 @@ menu_t SaveDef =
|
|||
80,54,
|
||||
0
|
||||
};
|
||||
*/
|
||||
|
||||
//
|
||||
// M_ReadSaveStrings
|
||||
// read the strings from the savegame files
|
||||
//
|
||||
/*
|
||||
void M_ReadSaveStrings(void)
|
||||
{
|
||||
FILE* handle;
|
||||
int count;
|
||||
int i;
|
||||
char name[256];
|
||||
int fd;
|
||||
int i, j;
|
||||
char name[64];
|
||||
uint16_t fc_path[64];
|
||||
|
||||
for (i = 0;i < load_end;i++)
|
||||
{
|
||||
sprintf(name,SAVEGAMENAME"%d.dsg",i);
|
||||
|
||||
handle = fopen (name, "r");
|
||||
if (handle == NULL)
|
||||
{
|
||||
strcpy(&savegamestrings[i][0],EMPTYSTRING);
|
||||
LoadMenu[i].status = 0;
|
||||
continue;
|
||||
}
|
||||
//count = read (handle, &savegamestrings[i], SAVESTRINGSIZE);
|
||||
//fread ( dest, size elements, count elements, FILE handle );
|
||||
count= fread (&savegamestrings[i], SAVESTRINGSIZE, 1, handle);
|
||||
|
||||
fclose (handle);
|
||||
LoadMenu[i].status = 1;
|
||||
sprintf(name, SAVEGAMENAME "%d.dsg", i);
|
||||
memcpy(fc_path, u"\\\\fls0\\", 14);
|
||||
for (j = 0; name[j]; j++)
|
||||
fc_path[j+7] = name[j];
|
||||
fc_path[j+7] = 0x0000;
|
||||
|
||||
fd = Bfile_OpenFile_OS(fc_path, READ, 0);
|
||||
|
||||
if(fd < 0) {
|
||||
CGDstrcpy(savegamestrings[i], EMPTYSTRING);
|
||||
LoadMenu[i].status = 0;
|
||||
}
|
||||
else {
|
||||
Bfile_ReadFile_OS(fd, savegamestrings[i], SAVESTRINGSIZE, -1);
|
||||
LoadMenu[i].status = 1;
|
||||
Bfile_CloseFile_OS(fd);
|
||||
}
|
||||
}
|
||||
|
||||
I_ReinitAfterError();
|
||||
}
|
||||
|
||||
|
||||
|
@ -503,19 +505,7 @@ void M_DrawLoad(void)
|
|||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void M_LoadGame(int choice)
|
||||
{
|
||||
(void)choice;
|
||||
M_StartMessage(NOTIMP, NULL, true);
|
||||
}
|
||||
|
||||
void M_SaveGame(int choice)
|
||||
{
|
||||
(void)choice;
|
||||
M_StartMessage(NOTIMP, NULL, true);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw border for the savegame description
|
||||
|
@ -536,6 +526,106 @@ void M_DrawSaveLoadBorder(int x,int y)
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// User wants to load this game
|
||||
//
|
||||
void M_LoadSelect(int choice)
|
||||
{
|
||||
(void)choice;
|
||||
/* char name[256];
|
||||
|
||||
if (M_CheckParm("-cdrom"))
|
||||
sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",choice);
|
||||
else
|
||||
sprintf(name,SAVEGAMENAME"%d.dsg",choice);
|
||||
G_LoadGame (name);
|
||||
M_ClearMenus (); */
|
||||
}
|
||||
|
||||
//
|
||||
// Selected from DOOM menu
|
||||
//
|
||||
void M_LoadGame(int choice)
|
||||
{
|
||||
if (netgame)
|
||||
{
|
||||
M_StartMessage(LOADNET,NULL,false);
|
||||
return;
|
||||
}
|
||||
|
||||
M_SetupNextMenu(&LoadDef);
|
||||
M_ReadSaveStrings();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// M_SaveGame & Cie.
|
||||
//
|
||||
void M_DrawSave(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
V_DrawPatchDirect (72,28,0,W_CacheLumpNamePatch("M_SAVEG",PU_CACHE));
|
||||
for (i = 0;i < load_end; i++)
|
||||
{
|
||||
M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i);
|
||||
M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]);
|
||||
}
|
||||
|
||||
if (saveStringEnter)
|
||||
{
|
||||
i = M_StringWidth(savegamestrings[saveSlot]);
|
||||
M_WriteText(LoadDef.x + i,LoadDef.y+LINEHEIGHT*saveSlot,"_");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// M_Responder calls this when user is finished
|
||||
//
|
||||
void M_DoSave(int slot)
|
||||
{
|
||||
G_SaveGame (slot,savegamestrings[slot]);
|
||||
M_ClearMenus ();
|
||||
|
||||
// PICK QUICKSAVE SLOT YET?
|
||||
if (quickSaveSlot == -2)
|
||||
quickSaveSlot = slot;
|
||||
}
|
||||
|
||||
//
|
||||
// User wants to save. Start string input for M_Responder
|
||||
//
|
||||
void M_SaveSelect(int choice)
|
||||
{
|
||||
// we are going to be intercepting all chars
|
||||
saveStringEnter = 1;
|
||||
|
||||
saveSlot = choice;
|
||||
CGDstrcpy(saveOldString,savegamestrings[choice]);
|
||||
if (!strcmp(savegamestrings[choice],EMPTYSTRING))
|
||||
savegamestrings[choice][0] = 0;
|
||||
saveCharIndex = strlen(savegamestrings[choice]);
|
||||
}
|
||||
|
||||
//
|
||||
// Selected from DOOM menu
|
||||
//
|
||||
void M_SaveGame(int choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
if (!usergame)
|
||||
{
|
||||
M_StartMessage(SAVEDEAD,NULL,false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
M_SetupNextMenu(&SaveDef);
|
||||
M_ReadSaveStrings();
|
||||
}
|
||||
|
||||
//
|
||||
// Read This Menus
|
||||
|
@ -995,6 +1085,48 @@ boolean M_Responder (event_t* ev)
|
|||
if (ch == -1)
|
||||
return false;
|
||||
|
||||
// Save Game string input
|
||||
if (saveStringEnter)
|
||||
{
|
||||
switch(ch)
|
||||
{
|
||||
case KEY_BACKSPACE:
|
||||
if (saveCharIndex > 0)
|
||||
{
|
||||
saveCharIndex--;
|
||||
savegamestrings[saveSlot][saveCharIndex] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_ESCAPE:
|
||||
saveStringEnter = 0;
|
||||
CGDstrcpy(&savegamestrings[saveSlot][0],saveOldString);
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
saveStringEnter = 0;
|
||||
if (savegamestrings[saveSlot][0])
|
||||
M_DoSave(saveSlot);
|
||||
break;
|
||||
|
||||
default:
|
||||
ch = (ch >= 'a' && ch <= 'z') ? (ch & ~0x20) : ch;
|
||||
if (ch != 32)
|
||||
if (ch-HU_FONTSTART < 0 || ch-HU_FONTSTART >= HU_FONTSIZE)
|
||||
break;
|
||||
if (ch >= 32 && ch <= 127 &&
|
||||
saveCharIndex < SAVESTRINGSIZE-1 &&
|
||||
M_StringWidth(savegamestrings[saveSlot]) <
|
||||
(SAVESTRINGSIZE-2)*8)
|
||||
{
|
||||
savegamestrings[saveSlot][saveCharIndex++] = ch;
|
||||
savegamestrings[saveSlot][saveCharIndex] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Take care of any messages that need input
|
||||
if (messageToPrint)
|
||||
{
|
||||
|
|
|
@ -90,6 +90,37 @@ int M_DrawText ( int x, int y, boolean direct, char* string )
|
|||
//
|
||||
// M_WriteFile
|
||||
//
|
||||
boolean M_WriteFile(char const *name, void *source, int length)
|
||||
{
|
||||
uint16_t fc_path[100] = u"\\\\fls0\\";
|
||||
size_t size = length;
|
||||
int j = 7;
|
||||
int rc, fd;
|
||||
|
||||
for (int i = 0; name[i]; i++)
|
||||
fc_path[j++] = name[i];
|
||||
fc_path[j++] = 0x0000;
|
||||
|
||||
Bfile_DeleteEntry(fc_path);
|
||||
|
||||
rc = Bfile_CreateEntry_OS(fc_path, CREATEMODE_FILE, &size);
|
||||
if (rc < 0) {
|
||||
/* Displaying the error message destroys the save data, so quit */
|
||||
I_Error("Bfile_CreateEntry_OS(%s, %d bytes): %d", name, length, rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
fd = Bfile_OpenFile_OS(fc_path, WRITE, 0);
|
||||
if (fd < 0) {
|
||||
I_Error("Bfile_OpenFile_OS(%s): %d", name, fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
Bfile_WriteFile_OS(fd, source, length);
|
||||
Bfile_CloseFile_OS(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// DEFAULTS
|
||||
//
|
||||
|
@ -118,4 +149,4 @@ extern int screenblocks;
|
|||
extern int showMessages;
|
||||
|
||||
int numdefaults;
|
||||
char* defaultfile;
|
||||
char* defaultfile;
|
||||
|
|
250
cgdoom/p_saveg.c
250
cgdoom/p_saveg.c
|
@ -71,6 +71,253 @@ void P_ArchivePlayers (void)
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// P_UnArchivePlayers
|
||||
//
|
||||
void P_UnArchivePlayers (void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
PADSAVEP();
|
||||
|
||||
memcpy (&players[i],save_p, sizeof(player_t));
|
||||
save_p += sizeof(player_t);
|
||||
|
||||
// will be set when unarc thinker
|
||||
players[i].mo = NULL;
|
||||
players[i].message = NULL;
|
||||
players[i].attacker = NULL;
|
||||
|
||||
for (j=0 ; j<NUMPSPRITES ; j++)
|
||||
{
|
||||
if (players[i]. psprites[j].state)
|
||||
{
|
||||
players[i]. psprites[j].state
|
||||
= (state_t *)&states[ (int)players[i].psprites[j].state ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_ArchiveWorld
|
||||
//
|
||||
void P_ArchiveWorld (void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
sector_t* sec;
|
||||
line_t* li;
|
||||
side_t* si;
|
||||
short* put;
|
||||
|
||||
put = (short *)save_p;
|
||||
|
||||
// do sectors
|
||||
for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
|
||||
{
|
||||
*put++ = sec->floorheight >> FRACBITS;
|
||||
*put++ = sec->ceilingheight >> FRACBITS;
|
||||
*put++ = sec->floorpic;
|
||||
*put++ = sec->ceilingpic;
|
||||
*put++ = sec->lightlevel;
|
||||
*put++ = sec->special; // needed?
|
||||
*put++ = sec->tag; // needed?
|
||||
}
|
||||
|
||||
|
||||
// do lines
|
||||
for (i=0, li = lines ; i<numlines ; i++,li++)
|
||||
{
|
||||
*put++ = li->flags;
|
||||
*put++ = li->special;
|
||||
*put++ = li->tag;
|
||||
for (j=0 ; j<2 ; j++)
|
||||
{
|
||||
if (li->sidenum[j] == -1)
|
||||
continue;
|
||||
|
||||
si = &sides[li->sidenum[j]];
|
||||
|
||||
*put++ = si->textureoffset >> FRACBITS;
|
||||
*put++ = si->rowoffset >> FRACBITS;
|
||||
*put++ = si->toptexture;
|
||||
*put++ = si->bottomtexture;
|
||||
*put++ = si->midtexture;
|
||||
}
|
||||
}
|
||||
|
||||
save_p = (byte *)put;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// P_UnArchiveWorld
|
||||
//
|
||||
void P_UnArchiveWorld (void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
sector_t* sec;
|
||||
line_t* li;
|
||||
side_t* si;
|
||||
short* get;
|
||||
|
||||
get = (short *)save_p;
|
||||
|
||||
// do sectors
|
||||
for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
|
||||
{
|
||||
sec->floorheight = *get++ << FRACBITS;
|
||||
sec->ceilingheight = *get++ << FRACBITS;
|
||||
sec->floorpic = *get++;
|
||||
sec->ceilingpic = *get++;
|
||||
sec->lightlevel = *get++;
|
||||
sec->special = *get++; // needed?
|
||||
sec->tag = *get++; // needed?
|
||||
sec->specialdata = 0;
|
||||
sec->soundtarget = 0;
|
||||
}
|
||||
|
||||
// do lines
|
||||
for (i=0, li = lines ; i<numlines ; i++,li++)
|
||||
{
|
||||
li->flags = *get++;
|
||||
li->special = *get++;
|
||||
li->tag = *get++;
|
||||
for (j=0 ; j<2 ; j++)
|
||||
{
|
||||
if (li->sidenum[j] == -1)
|
||||
continue;
|
||||
si = &sides[li->sidenum[j]];
|
||||
si->textureoffset = *get++ << FRACBITS;
|
||||
si->rowoffset = *get++ << FRACBITS;
|
||||
si->toptexture = *get++;
|
||||
si->bottomtexture = *get++;
|
||||
si->midtexture = *get++;
|
||||
}
|
||||
}
|
||||
save_p = (byte *)get;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Thinkers
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
tc_end,
|
||||
tc_mobj
|
||||
|
||||
} thinkerclass_t;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// P_ArchiveThinkers
|
||||
//
|
||||
void P_ArchiveThinkers (void)
|
||||
{
|
||||
thinker_t* th;
|
||||
mobj_t* mobj;
|
||||
|
||||
// save off the current thinkers
|
||||
for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
|
||||
{
|
||||
if (th->function == TP_MobjThinker)
|
||||
{
|
||||
*save_p++ = tc_mobj;
|
||||
PADSAVEP();
|
||||
mobj = (mobj_t *)save_p;
|
||||
memcpy (mobj, th, sizeof(*mobj));
|
||||
save_p += sizeof(*mobj);
|
||||
mobj->state = (state_t *)(mobj->state - states);
|
||||
|
||||
if (mobj->player)
|
||||
mobj->player = (player_t *)((mobj->player-players) + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// I_Error would overwrite VRAM, thus screens[0], thus the save buffer
|
||||
// I_Error ("P_ArchiveThinkers: Unknown thinker function");
|
||||
}
|
||||
|
||||
// add a terminating marker
|
||||
*save_p++ = tc_end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// P_UnArchiveThinkers
|
||||
//
|
||||
void P_UnArchiveThinkers (void)
|
||||
{
|
||||
byte tclass;
|
||||
thinker_t* currentthinker;
|
||||
thinker_t* next;
|
||||
mobj_t* mobj;
|
||||
|
||||
// remove all the current thinkers
|
||||
currentthinker = thinkercap.next;
|
||||
while (currentthinker != &thinkercap)
|
||||
{
|
||||
next = currentthinker->next;
|
||||
|
||||
if (currentthinker->function == TP_MobjThinker)
|
||||
P_RemoveMobj ((mobj_t *)currentthinker);
|
||||
else
|
||||
Z_Free (currentthinker);
|
||||
|
||||
currentthinker = next;
|
||||
}
|
||||
|
||||
P_InitThinkers ();
|
||||
|
||||
// read in saved thinkers
|
||||
while (1)
|
||||
{
|
||||
tclass = *save_p++;
|
||||
switch (tclass)
|
||||
{
|
||||
case tc_end:
|
||||
return; // end of list
|
||||
|
||||
case tc_mobj:
|
||||
PADSAVEP();
|
||||
mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
|
||||
memcpy (mobj, save_p, sizeof(*mobj));
|
||||
save_p += sizeof(*mobj);
|
||||
mobj->state = (state_t *)&states[(int)mobj->state];
|
||||
mobj->target = NULL;
|
||||
if (mobj->player)
|
||||
{
|
||||
mobj->player = &players[(int)mobj->player-1];
|
||||
mobj->player->mo = mobj;
|
||||
}
|
||||
P_SetThingPosition (mobj);
|
||||
mobj->info = (mobjinfo_t *)&mobjinfo[mobj->type];
|
||||
mobj->floorz = mobj->subsector->sector->floorheight;
|
||||
mobj->ceilingz = mobj->subsector->sector->ceilingheight;
|
||||
mobj->thinker.function = TP_MobjThinker;
|
||||
P_AddThinker (&mobj->thinker, mobj);
|
||||
break;
|
||||
|
||||
default:
|
||||
// I_Error would overwrite VRAM, thus screens[0], thus the save buffer
|
||||
// I_Error ("Unknown tclass %i in savegame",tclass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// P_ArchiveSpecials
|
||||
|
@ -325,7 +572,8 @@ void P_UnArchiveSpecials (void)
|
|||
break;
|
||||
|
||||
default:
|
||||
I_Error ("P_UnarchiveSpecials:Unknown tclass %i in savegame",tclass);
|
||||
// I_Error would overwrite VRAM, thus screens[0], thus the save buffer
|
||||
// I_Error ("P_UnarchiveSpecials:Unknown tclass %i in savegame",tclass);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -120,6 +120,35 @@ static int DoomKeyToKeycode(int key)
|
|||
case SKEY_FRAMESKIP: return KEYCODE_VARS;
|
||||
case SKEY_PROFILER: return KEYCODE_RIGHTP;
|
||||
|
||||
/* Alphabetic keys */
|
||||
case 'A': return KEYCODE_XOT;
|
||||
case 'B': return KEYCODE_LOG;
|
||||
case 'C': return KEYCODE_LN;
|
||||
case 'D': return KEYCODE_SIN;
|
||||
case 'E': return KEYCODE_COS;
|
||||
case 'F': return KEYCODE_TAN;
|
||||
case 'G': return KEYCODE_FRAC;
|
||||
case 'H': return KEYCODE_FD;
|
||||
case 'I': return KEYCODE_LEFTP;
|
||||
case 'J': return KEYCODE_RIGHTP;
|
||||
case 'K': return KEYCODE_COMMA;
|
||||
case 'L': return KEYCODE_ARROW;
|
||||
case 'M': return KEYCODE_7;
|
||||
case 'N': return KEYCODE_8;
|
||||
case 'O': return KEYCODE_9;
|
||||
case 'P': return KEYCODE_4;
|
||||
case 'Q': return KEYCODE_5;
|
||||
case 'R': return KEYCODE_6;
|
||||
case 'S': return KEYCODE_MUL;
|
||||
case 'T': return KEYCODE_DIV;
|
||||
case 'U': return KEYCODE_1;
|
||||
case 'V': return KEYCODE_2;
|
||||
case 'W': return KEYCODE_3;
|
||||
case 'X': return KEYCODE_PLUS;
|
||||
case 'Y': return KEYCODE_MINUS;
|
||||
case 'Z': return KEYCODE_0;
|
||||
case KEY_BACKSPACE: return KEYCODE_DEL;
|
||||
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue